summaryrefslogtreecommitdiff
path: root/test/scudo
diff options
context:
space:
mode:
authorKostya Kortchinsky <kostyak@google.com>2016-09-19 21:11:55 +0000
committerKostya Kortchinsky <kostyak@google.com>2016-09-19 21:11:55 +0000
commit42cfe466e6e4fc0580d7945cc5c346318694224f (patch)
tree37b6fd0ac6a172fd5ceaa9e9b6bd31715c1f2079 /test/scudo
parent96f3c80a994d3fe69f79e398b736a46801784524 (diff)
[scudo] Modify Scudo to use its own Secondary Allocator
Summary: The Sanitizer Secondary Allocator was not entirely ideal was Scudo for several reasons: decent amount of unneeded code, redundant checks already performed by the front end, unneeded data structures, difficulty to properly protect the secondary chunks header. Given that the second allocator is pretty straight forward, Scudo will use its own, trimming all the unneeded code off of the Sanitizer one. A significant difference in terms of security is that now each secondary chunk is preceded and followed by a guard page, thus mitigating overflows into and from the chunk. A test was added as well to illustrate the overflow & underflow situations into the guard pages. Reviewers: kcc Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D24737 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@281938 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/scudo')
-rw-r--r--test/scudo/secondary.cpp54
1 files changed, 54 insertions, 0 deletions
diff --git a/test/scudo/secondary.cpp b/test/scudo/secondary.cpp
new file mode 100644
index 000000000..7a634a81e
--- /dev/null
+++ b/test/scudo/secondary.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_scudo %s -o %t
+// RUN: %run %t after 2>&1 | FileCheck %s
+// RUN: %run %t before 2>&1 | FileCheck %s
+
+// Test that we hit a guard page when writing past the end of a chunk
+// allocated by the Secondary allocator, or writing too far in front of it.
+
+#include <malloc.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <assert.h>
+
+void handler(int signo, siginfo_t *info, void *uctx) {
+ if (info->si_code == SEGV_ACCERR) {
+ fprintf(stderr, "SCUDO SIGSEGV\n");
+ exit(0);
+ }
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ // The size must be large enough to be serviced by the secondary allocator.
+ long page_size = sysconf(_SC_PAGESIZE);
+ size_t size = (1U << 17) + page_size;
+ struct sigaction a;
+
+ assert(argc == 2);
+ memset(&a, 0, sizeof(a));
+ a.sa_sigaction = handler;
+ a.sa_flags = SA_SIGINFO;
+
+ char *p = (char *)malloc(size);
+ if (!p)
+ return 1;
+ memset(p, 'A', size); // This should not trigger anything.
+ // Set up the SIGSEGV handler now, as the rest should trigger an AV.
+ sigaction(SIGSEGV, &a, nullptr);
+ if (!strcmp(argv[1], "after")) {
+ for (int i = 0; i < page_size; i++)
+ p[size + i] = 'A';
+ }
+ if (!strcmp(argv[1], "before")) {
+ for (int i = 1; i < page_size; i++)
+ p[-i] = 'A';
+ }
+ free(p);
+
+ return 1; // A successful test means we shouldn't reach this.
+}
+
+// CHECK: SCUDO SIGSEGV