xref: /llvm-project/compiler-rt/test/asan/TestCases/Linux/read_binary_name_regtest.c (revision dc37287320cc074a49d73035674891be06c65a42)
1 // Regression test for https://crbug.com/502974, where ASan was unable to read
2 // the binary name because of sandbox restrictions.
3 // This test uses seccomp-BPF to restrict the readlink() system call and makes
4 // sure ASan is still able to
5 // Disable symbolizing results, since this will invoke llvm-symbolizer, which
6 // will be unable to resolve its $ORIGIN due to readlink() restriction and will
7 // thus fail to start, causing the test to die with SIGPIPE when attempting to
8 // talk to it.
9 // RUN: not ls /usr/include/linux/seccomp.h || ( %clang_asan %s -o %t && ( not env ASAN_OPTIONS=symbolize=0 %run %t 2>&1 ) | FileCheck %s )
10 // REQUIRES: shell
11 // UNSUPPORTED: android
12 
13 #include <errno.h>
14 #include <stddef.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <sys/prctl.h>
18 #include <sys/syscall.h>
19 #include <linux/filter.h>
20 #include <linux/seccomp.h>
21 
22 #ifndef __NR_readlink
23 # define __NR_readlink __NR_readlinkat
24 #endif
25 
26 #define syscall_nr (offsetof(struct seccomp_data, nr))
27 
corrupt()28 void corrupt() {
29   void *p = malloc(10);
30   free(p);
31   free(p);
32 }
33 
main()34 int main() {
35   prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
36 
37   struct sock_filter filter[] = {
38     /* Grab the system call number */
39     BPF_STMT(BPF_LD + BPF_W + BPF_ABS, syscall_nr),
40     // If this is __NR_readlink,
41     BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, __NR_readlink, 0, 1),
42     // return with EPERM,
43     BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | EPERM),
44     // otherwise allow the syscall.
45     BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW)
46   };
47   struct sock_fprog prog;
48   prog.len = (unsigned short)(sizeof(filter)/sizeof(filter[0]));
49   prog.filter = filter;
50 
51   int res = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
52   if (res != 0) {
53     fprintf(stderr, "PR_SET_SECCOMP unsupported!\n");
54   }
55   corrupt();
56   // CHECK: AddressSanitizer
57   // CHECK-NOT: reading executable name failed
58   return 0;
59 }
60