Skip to content

Commit

Permalink
libgcc/CET: Skip signal frames when unwinding shadow stack
Browse files Browse the repository at this point in the history
When -fcf-protection -mcet is used, I got

FAIL: g++.dg/eh/sighandle.C

(gdb) bt
 #0  _Unwind_RaiseException (exc=exc@entry=0x416ed0)
    at /export/gnu/import/git/sources/gcc/libgcc/unwind.inc:140
 #1  0x00007ffff7d9936b in __cxxabiv1::__cxa_throw (obj=<optimized out>,
    tinfo=0x403dd0 <typeinfo for int@@CXXABI_1.3>, dest=0x0)
    at /export/gnu/import/git/sources/gcc/libstdc++-v3/libsupc++/eh_throw.cc:90
 #2  0x0000000000401255 in sighandler (signo=11, si=0x7fffffffd6f8,
    uc=0x7fffffffd5c0)
    at /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.dg/eh/sighandle.C:9
 #3  <signal handler called> <<<< Signal frame which isn't on shadow stack
 #4  dosegv ()
    at /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.dg/eh/sighandle.C:14
 #5  0x00000000004012e3 in main ()
    at /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.dg/eh/sighandle.C:30
(gdb) p frames
$6 = 5
(gdb)

frame count should be 4, not 5.  This patch skips signal frames when
unwinding shadow stack.

gcc/testsuite/

	PR libgcc/85334
	* g++.dg/torture/pr85334.C: New test.

libgcc/

	PR libgcc/85334
	* unwind-generic.h (_Unwind_Frames_Increment): New.
	* config/i386/shadow-stack-unwind.h (_Unwind_Frames_Increment):
	Likewise.
	* unwind.inc (_Unwind_RaiseException_Phase2): Increment frame
	count with _Unwind_Frames_Increment.
	(_Unwind_ForcedUnwind_Phase2): Likewise.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@259502 138bc75d-0d04-0410-961f-82ee72b054a4
  • Loading branch information
hjl committed Apr 19, 2018
1 parent 47b6cf6 commit 20d1a07
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 2 deletions.
5 changes: 5 additions & 0 deletions gcc/testsuite/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
2018-04-19 H.J. Lu <hongjiu.lu@intel.com>

PR libgcc/85334
* g++.dg/torture/pr85334.C: New test.

2018-04-19 Jonathan Wakely <jwakely@redhat.com>

PR c++/85464 - missing location for -Wignored-qualifiers diagnostic
Expand Down
38 changes: 38 additions & 0 deletions gcc/testsuite/g++.dg/torture/pr85334.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// { dg-do run { target { i?86-*-linux* i?86-*-gnu* x86_64-*-linux* } } }
// { dg-require-effective-target cet }
// { dg-additional-options "-fexceptions -fnon-call-exceptions -fcf-protection -mcet" }

#include <signal.h>
#include <stdlib.h>

void sighandler (int signo, siginfo_t * si, void * uc)
{
throw (5);
}

char * dosegv ()
{
* ((volatile int *)0) = 12;
return 0;
}

int main ()
{
struct sigaction sa;
int status;

sa.sa_sigaction = sighandler;
sa.sa_flags = SA_SIGINFO;

status = sigaction (SIGSEGV, & sa, NULL);
status = sigaction (SIGBUS, & sa, NULL);

try {
dosegv ();
}
catch (int x) {
return (x != 5);
}

return 1;
}
10 changes: 10 additions & 0 deletions libgcc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
2018-04-19 H.J. Lu <hongjiu.lu@intel.com>

PR libgcc/85334
* unwind-generic.h (_Unwind_Frames_Increment): New.
* config/i386/shadow-stack-unwind.h (_Unwind_Frames_Increment):
Likewise.
* unwind.inc (_Unwind_RaiseException_Phase2): Increment frame
count with _Unwind_Frames_Increment.
(_Unwind_ForcedUnwind_Phase2): Likewise.

2018-04-19 H.J. Lu <hongjiu.lu@intel.com>

PR libgcc/85379
Expand Down
5 changes: 5 additions & 0 deletions libgcc/config/i386/shadow-stack-unwind.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
} \
} \
while (0)

/* Increment frame count. Skip signal frames. */
#undef _Unwind_Frames_Increment
#define _Unwind_Frames_Increment(context, frames) \
if (!_Unwind_IsSignalFrame (context)) frames++
3 changes: 3 additions & 0 deletions libgcc/unwind-generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,4 +291,7 @@ EXCEPTION_DISPOSITION _GCC_specific_handler (PEXCEPTION_RECORD, void *,
/* Additional actions to unwind number of stack frames. */
#define _Unwind_Frames_Extra(frames)

/* Increment frame count. */
#define _Unwind_Frames_Increment(context, frames) frames++

#endif /* unwind.h */
4 changes: 2 additions & 2 deletions libgcc/unwind.inc
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ _Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc,
gcc_assert (!match_handler);

uw_update_context (context, &fs);
frames++;
_Unwind_Frames_Increment (context, frames);
}

*frames_p = frames;
Expand Down Expand Up @@ -190,7 +190,7 @@ _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
/* Update cur_context to describe the same frame as fs, and discard
the previous context if necessary. */
uw_advance_context (context, &fs);
frames++;
_Unwind_Frames_Increment (context, frames);
}

*frames_p = frames;
Expand Down

0 comments on commit 20d1a07

Please sign in to comment.