i386: Properly pop restore token in signal frame
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 10 Feb 2020 15:58:45 +0000 (07:58 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 10 Feb 2020 15:59:10 +0000 (07:59 -0800)
commitbf6465d0461234ccd45ae34d5e2375a0bee0081d
tree71a56036daba549bcf0290f3780a4b27a1304c37
parent1cad5e89a9e1b4ffa47bc6e3551643b342f6cfe8
i386: Properly pop restore token in signal frame

Linux CET kernel places a restore token on shadow stack for signal
handler to enhance security.  The restore token is 8 byte and aligned
to 8 bytes.  It is usually transparent to user programs since kernel
will pop the restore token when signal handler returns.  But when an
exception is thrown from a signal handler, now we need to pop the
restore token from shadow stack.  For x86-64, we just need to treat
the signal frame as normal frame.  For i386, we need to search for
the restore token to check if the original shadow stack is 8 byte
aligned.  If the original shadow stack is 8 byte aligned, we just
need to pop 2 slots, one restore token, from shadow stack.  Otherwise,
we need to pop 3 slots, one restore token + 4 byte padding, from
shadow stack.

This patch also includes 2 tests, one has a restore token with 4 byte
padding and one without.

Tested on Linux/x86-64 CET machine with and without -m32.

libgcc/

PR libgcc/85334
* config/i386/shadow-stack-unwind.h (_Unwind_Frames_Increment):
New.

gcc/testsuite/

PR libgcc/85334
* g++.target/i386/pr85334-1.C: New test.
* g++.target/i386/pr85334-2.C: Likewise.
gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.target/i386/pr85334-1.C [new file with mode: 0644]
gcc/testsuite/g++.target/i386/pr85334-2.C [new file with mode: 0644]
libgcc/config/i386/shadow-stack-unwind.h