diff options
author | Derek Bruening <bruening@google.com> | 2016-05-31 13:21:03 +0000 |
---|---|---|
committer | Derek Bruening <bruening@google.com> | 2016-05-31 13:21:03 +0000 |
commit | 0573d6c7f326a08eeff6e595fd77045a0210c32a (patch) | |
tree | 9da5bc281151889b2b8b836cbf9373fb94105a2d /test/esan | |
parent | 124601f8dc708132bf13ccdfbe927b8118b68136 (diff) |
[esan] Intercept and chain signal handlers
Summary:
In preparation for fault-based shadow memory iteration, we add support for
our own signal handler by adding app signal handler interception as well as
chaining for SIGSEGV. This is done in a simple manner: we do not honor the
app's alternate stack nor any sigaction flags for SIGSEGV.
Adds a new test of transparency in app signal handling.
Reviewers: aizatsky
Subscribers: filcab, kubabrecka, vitalybuka, zhaoqin, kcc, eugenis, llvm-commits
Differential Revision: http://reviews.llvm.org/D20577
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@271272 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/esan')
-rw-r--r-- | test/esan/TestCases/workingset-signal-posix.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/test/esan/TestCases/workingset-signal-posix.cpp b/test/esan/TestCases/workingset-signal-posix.cpp new file mode 100644 index 000000000..c0245760c --- /dev/null +++ b/test/esan/TestCases/workingset-signal-posix.cpp @@ -0,0 +1,59 @@ +// RUN: %clang_esan_wset -O0 %s -o %t 2>&1 +// RUN: %run %t 2>&1 | FileCheck %s + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <setjmp.h> +#include <assert.h> + +sigjmp_buf mark; + +static void SignalHandler(int Sig) { + if (Sig == SIGSEGV) { + fprintf(stderr, "Handling SIGSEGV for signal\n"); + siglongjmp(mark, 1); + } + exit(1); +} + +static void SigactionHandler(int Sig, siginfo_t *Info, void *Ctx) { + if (Sig == SIGSEGV) { + fprintf(stderr, "Handling SIGSEGV for sigaction\n"); + siglongjmp(mark, 1); + } + exit(1); +} + +int main(int argc, char **argv) { + __sighandler_t Prior = signal(SIGSEGV, SignalHandler); + assert(Prior == SIG_DFL); + if (sigsetjmp(mark, 1) == 0) + *((volatile int *)(ssize_t)argc) = 42; // Raise SIGSEGV + fprintf(stderr, "Past longjmp for signal\n"); + + Prior = signal(SIGSEGV, SIG_DFL); + assert(Prior == SignalHandler); + + struct sigaction SigAct; + SigAct.sa_sigaction = SigactionHandler; + int Res = sigfillset(&SigAct.sa_mask); + assert(Res == 0); + SigAct.sa_flags = SA_SIGINFO; + Res = sigaction(SIGSEGV, &SigAct, NULL); + assert(Res == 0); + + if (sigsetjmp(mark, 1) == 0) + *((volatile int *)(ssize_t)argc) = 42; // Raise SIGSEGV + fprintf(stderr, "Past longjmp for sigaction\n"); + + Res = sigaction(SIGSEGV, NULL, &SigAct); + assert(Res == 0); + assert(SigAct.sa_sigaction == SigactionHandler); + + return 0; +} +// CHECK: Handling SIGSEGV for signal +// CHECK-NEXT: Past longjmp for signal +// CHECK-NEXT: Handling SIGSEGV for sigaction +// CHECK-NEXT: Past longjmp for sigaction |