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 28 void corrupt() { 29 void *p = malloc(10); 30 free(p); 31 free(p); 32 } 33 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