summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2015-06-30 15:18:03 +0000
committerAlexander Potapenko <glider@google.com>2015-06-30 15:18:03 +0000
commitddbca29d883ef1ccdaa4acb7803d69cc2dba0e01 (patch)
treeb6d79b5dae3791e662c1bb89f9a3c4b80d145ad9 /test
parenta522d7328d0e46cc82e007890ae549241618ef0e (diff)
[ASan] Add a regression test for r240960 (https://crbug.com/502974)
The test simulates a sandbox that prevents the program from calling readlink(). ASan is supposed to still be able to print the executable name regardless of that. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@241072 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/asan/TestCases/Linux/read_binary_name_regtest.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/test/asan/TestCases/Linux/read_binary_name_regtest.c b/test/asan/TestCases/Linux/read_binary_name_regtest.c
new file mode 100644
index 000000000..2fab4c3b2
--- /dev/null
+++ b/test/asan/TestCases/Linux/read_binary_name_regtest.c
@@ -0,0 +1,48 @@
+// Regression test for https://crbug.com/502974, where ASan was unable to read
+// the binary name because of sandbox restrictions.
+// This test uses seccomp-BPF to restrict the readlink() system call and makes
+// sure ASan is still able to
+// RUN: %clang_asan %s -o %t && not %run %t 2>&1 | FileCheck %s
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+
+#define syscall_nr (offsetof(struct seccomp_data, nr))
+
+void corrupt() {
+ void *p = malloc(10);
+ free(p);
+ free(p);
+}
+
+int main() {
+ prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+
+ struct sock_filter filter[] = {
+ /* Grab the system call number */
+ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, syscall_nr),
+ // If this is __NR_readlink,
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, __NR_readlink, 0, 1),
+ // return with EPERM,
+ BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | EPERM),
+ // otherwise allow the syscall.
+ BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW)
+ };
+ struct sock_fprog prog;
+ prog.len = (unsigned short)(sizeof(filter)/sizeof(filter[0]));
+ prog.filter = filter;
+
+ int res = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
+ if (res != 0) {
+ fprintf(stderr, "PR_SET_SECCOMP unsupported!\n");
+ }
+ corrupt();
+ // CHECK: AddressSanitizer
+ // CHECK-NOT: reading executable name failed
+ return 0;
+}