[ASan] Add a regression test for r240960 (https://crbug.com/502974)
authorAlexander Potapenko <glider@google.com>
Tue, 30 Jun 2015 15:18:03 +0000 (15:18 +0000)
committerAlexander Potapenko <glider@google.com>
Tue, 30 Jun 2015 15:18:03 +0000 (15:18 +0000)
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.

llvm-svn: 241072

compiler-rt/test/asan/TestCases/Linux/read_binary_name_regtest.c [new file with mode: 0644]

diff --git a/compiler-rt/test/asan/TestCases/Linux/read_binary_name_regtest.c b/compiler-rt/test/asan/TestCases/Linux/read_binary_name_regtest.c
new file mode 100644 (file)
index 0000000..2fab4c3
--- /dev/null
@@ -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;
+}