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
28void corrupt() {
29 void *p = malloc(size: 10);
30 free(ptr: p);
31 free(ptr: p);
32}
33
34int 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, format: "PR_SET_SECCOMP unsupported!\n");
54 }
55 corrupt();
56 // CHECK: AddressSanitizer
57 // CHECK-NOT: reading executable name failed
58 return 0;
59}
60

source code of compiler-rt/test/asan/TestCases/Linux/read_binary_name_regtest.c