x86: Check corrupted return address when unwinding stack
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 11 Aug 2022 23:21:23 +0000 (16:21 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 17 Oct 2022 21:21:47 +0000 (14:21 -0700)
commit9072db9d5b549db5e2f14335ac0adc7735d43bc6
tree0c48f84e70e2698f8109b43b7abb97639dc58928
parent84807af0ca6dfdb81abb8e925ce32acbcab29868
x86: Check corrupted return address when unwinding stack

If shadow stack is enabled, when unwinding stack, we count how many stack
frames we pop to reach the landing pad and adjust shadow stack by the same
amount.  When counting the stack frame, we compare the return address on
normal stack against the return address on shadow stack.  If they don't
match, return _URC_FATAL_PHASE2_ERROR for the corrupted return address on
normal stack.  Don't check the return address for

1. Non-catchable exception where exception_class == 0.  Process will be
terminated.
2. Zero return address which marks the outermost stack frame.
3. Signal stack frame since kernel puts a restore token on shadow stack.

* unwind-generic.h (_Unwind_Frames_Increment): Add the EXC
argument.
* unwind.inc (_Unwind_RaiseException_Phase2): Pass EXC to
_Unwind_Frames_Increment.
(_Unwind_ForcedUnwind_Phase2): Likewise.
* config/i386/shadow-stack-unwind.h (_Unwind_Frames_Increment):
Take the EXC argument.  Return _URC_FATAL_PHASE2_ERROR if the
return address on normal stack doesn't match the return address
on shadow stack.
libgcc/config/i386/shadow-stack-unwind.h
libgcc/unwind-generic.h
libgcc/unwind.inc