summaryrefslogtreecommitdiff
path: root/test/esan
diff options
context:
space:
mode:
authorDerek Bruening <bruening@google.com>2016-05-31 13:21:03 +0000
committerDerek Bruening <bruening@google.com>2016-05-31 13:21:03 +0000
commit0573d6c7f326a08eeff6e595fd77045a0210c32a (patch)
tree9da5bc281151889b2b8b836cbf9373fb94105a2d /test/esan
parent124601f8dc708132bf13ccdfbe927b8118b68136 (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.cpp59
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