[RFC PATCH 0/3] arm64: Implement reliable stack trace

Madhavan T. Venkataraman madvenka at linux.microsoft.com
Fri Jan 29 16:39:35 EST 2021



On 1/28/21 9:26 AM, Josh Poimboeuf wrote:
> 
> Hi all,
> 
> I know this is an old patch set, but I'm not able to see the context,
> because I'm not subcribed to the ML.  For future patch sets can you also
> add live-patching and lkml?
> 
> Are we still considering the shadow stack thing?  Just wondering why
> we're talking about objtool again.
> 

I think that we are still considering the shadow stack thing. No discussion
has happened. Based on my limited knowledge of shadow stacks, I think that
shadow stacks do not get rid of objtool.

Here is what I feel about shadow stacks. Please correct me if I am wrong.

Advantages
==========

The only advantage in shadow stacks that I can see is that stack corruption
will not prevent unwinding from happening (unless the shadow stack gets
corrupted somehow).

Issues common with frame pointers
=================================

- The compiler has to generate the prolog and epilog. If we cannot trust the
  compiler to generate these for frame pointers, can we trust it to
  generate these for the shadow stack? If we can't, we would need objtool
  anyway.

- The compiler would only generate shadow stack code for C functions.
  For assembly functions, it has to be done by hand. So, objtool has to
  check this anyway, right?

- Inline assembly in C functions can screw up the shadow stack just like
  it can screw up frame pointers. Again, objtool needs to check.

- Performance hit because of the extra overhead in the prolog and the
  epilog.

Issues unique to shadow stacks
==============================

- Performance hit because of the extra cache and memory footprint. There is
  a paper that says that the performance hit can be as high as 10%. Using
  a parallel shadow stack reduces the hit to about 3.5%. But then again,
  the characteristics for the kernel may be different.

- A separate register has to be reserved for holding the shadow stack
  pointer. The compiler (gcc) has to be changed to not use this register for
  other purposes. And we have to trust that there are no compiler bugs
  in this area. All assembly code that currently uses this register for
  anything needs to be reviewed and potentially changed. This includes
  all inline assembly code. BTW, I believe clang uses x18 for the shadow
  stack pointer register.

- Need to decide if we need a separate shadow stack for task, IRQ,
  overflow, etc. Or, use the same shadow stack. If it is the former,
  we use more memory and need to switch stacks. If it is the latter,
  we need to be aware of the boundaries between the different stack
  traces in the shadow stack.

- longjmp style situations require unwinding the shadow stack by several
  frames.

        - either unwind the shadow stack repeatedly until the return
          address matches with the original stack.

        - for userland code, the shadow stack pointer can be saved in
          setjmp and restored in longjmp. Something similar can be
          done in the kernel.

- Minor issue is the sizing of the shadow stack so there is no overflow.

Questions
=========

Do we have to worry about code that modifies the return address
of a function?

Madhavan



More information about the linux-arm-kernel mailing list