xref: /aosp_15_r20/external/compiler-rt/test/asan/TestCases/Linux/ptrace.cc (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316
2*7c3d14c8STreehugger Robot // XFAIL: android
3*7c3d14c8STreehugger Robot // XFAIL: mips
4*7c3d14c8STreehugger Robot //
5*7c3d14c8STreehugger Robot // RUN: %clangxx_asan -O0 %s -o %t && %run %t
6*7c3d14c8STreehugger Robot // RUN: %clangxx_asan -DPOSITIVE -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
7*7c3d14c8STreehugger Robot 
8*7c3d14c8STreehugger Robot #include <assert.h>
9*7c3d14c8STreehugger Robot #include <stdio.h>
10*7c3d14c8STreehugger Robot #include <sys/ptrace.h>
11*7c3d14c8STreehugger Robot #include <sys/types.h>
12*7c3d14c8STreehugger Robot #include <sys/user.h>
13*7c3d14c8STreehugger Robot #include <sys/wait.h>
14*7c3d14c8STreehugger Robot #include <unistd.h>
15*7c3d14c8STreehugger Robot #include <sys/uio.h> // for iovec
16*7c3d14c8STreehugger Robot #include <elf.h> // for NT_PRSTATUS
17*7c3d14c8STreehugger Robot #ifdef __aarch64__
18*7c3d14c8STreehugger Robot # include <asm/ptrace.h>
19*7c3d14c8STreehugger Robot #endif
20*7c3d14c8STreehugger Robot 
21*7c3d14c8STreehugger Robot #if defined(__i386__) || defined(__x86_64__)
22*7c3d14c8STreehugger Robot typedef user_regs_struct   regs_struct;
23*7c3d14c8STreehugger Robot typedef user_fpregs_struct fpregs_struct;
24*7c3d14c8STreehugger Robot #if defined(__i386__)
25*7c3d14c8STreehugger Robot #define REG_IP  eip
26*7c3d14c8STreehugger Robot #else
27*7c3d14c8STreehugger Robot #define REG_IP  rip
28*7c3d14c8STreehugger Robot #endif
29*7c3d14c8STreehugger Robot #define PRINT_REG_PC(__regs)    printf ("%lx\n", (unsigned long) (__regs.REG_IP))
30*7c3d14c8STreehugger Robot #define PRINT_REG_FP(__fpregs)  printf ("%lx\n", (unsigned long) (__fpregs.cwd))
31*7c3d14c8STreehugger Robot #define __PTRACE_FPREQUEST PTRACE_GETFPREGS
32*7c3d14c8STreehugger Robot 
33*7c3d14c8STreehugger Robot #elif defined(__aarch64__)
34*7c3d14c8STreehugger Robot typedef struct user_pt_regs      regs_struct;
35*7c3d14c8STreehugger Robot typedef struct user_fpsimd_state fpregs_struct;
36*7c3d14c8STreehugger Robot #define PRINT_REG_PC(__regs)    printf ("%x\n", (unsigned) (__regs.pc))
37*7c3d14c8STreehugger Robot #define PRINT_REG_FP(__fpregs)  printf ("%x\n", (unsigned) (__fpregs.fpsr))
38*7c3d14c8STreehugger Robot #define ARCH_IOVEC_FOR_GETREGSET
39*7c3d14c8STreehugger Robot 
40*7c3d14c8STreehugger Robot #elif defined(__powerpc64__)
41*7c3d14c8STreehugger Robot typedef struct pt_regs regs_struct;
42*7c3d14c8STreehugger Robot typedef elf_fpregset_t fpregs_struct;
43*7c3d14c8STreehugger Robot #define PRINT_REG_PC(__regs)    printf ("%lx\n", (unsigned long) (__regs.nip))
44*7c3d14c8STreehugger Robot #define PRINT_REG_FP(__fpregs)  printf ("%lx\n", (elf_greg_t)fpregs[32])
45*7c3d14c8STreehugger Robot #define ARCH_IOVEC_FOR_GETREGSET
46*7c3d14c8STreehugger Robot 
47*7c3d14c8STreehugger Robot #elif defined(__mips__)
48*7c3d14c8STreehugger Robot typedef struct pt_regs regs_struct;
49*7c3d14c8STreehugger Robot typedef elf_fpregset_t fpregs_struct;
50*7c3d14c8STreehugger Robot #define PRINT_REG_PC(__regs)    printf ("%lx\n", (unsigned long) (__regs.cp0_epc))
51*7c3d14c8STreehugger Robot #define PRINT_REG_FP(__fpregs)  printf ("%lx\n", (elf_greg_t) (__fpregs[32]))
52*7c3d14c8STreehugger Robot #define __PTRACE_FPREQUEST PTRACE_GETFPREGS
53*7c3d14c8STreehugger Robot 
54*7c3d14c8STreehugger Robot #elif defined(__arm__)
55*7c3d14c8STreehugger Robot # include <asm/ptrace.h>
56*7c3d14c8STreehugger Robot # include <sys/procfs.h>
57*7c3d14c8STreehugger Robot typedef struct pt_regs regs_struct;
58*7c3d14c8STreehugger Robot typedef char fpregs_struct[ARM_VFPREGS_SIZE];
59*7c3d14c8STreehugger Robot #define PRINT_REG_PC(__regs)    printf ("%x\n", (unsigned) (__regs.ARM_pc))
60*7c3d14c8STreehugger Robot #define PRINT_REG_FP(__fpregs)  printf ("%x\n", (unsigned) (__fpregs + 32 * 8))
61*7c3d14c8STreehugger Robot #define __PTRACE_FPREQUEST PTRACE_GETVFPREGS
62*7c3d14c8STreehugger Robot 
63*7c3d14c8STreehugger Robot #elif defined(__s390__)
64*7c3d14c8STreehugger Robot typedef _user_regs_struct   regs_struct;
65*7c3d14c8STreehugger Robot typedef _user_fpregs_struct fpregs_struct;
66*7c3d14c8STreehugger Robot #define PRINT_REG_PC(__regs)    printf ("%lx\n", (unsigned long) (__regs.psw.addr))
67*7c3d14c8STreehugger Robot #define PRINT_REG_FP(__fpregs)  printf ("%lx\n", (unsigned long) (__fpregs.fpc))
68*7c3d14c8STreehugger Robot #define ARCH_IOVEC_FOR_GETREGSET
69*7c3d14c8STreehugger Robot #endif
70*7c3d14c8STreehugger Robot 
71*7c3d14c8STreehugger Robot 
main(void)72*7c3d14c8STreehugger Robot int main(void) {
73*7c3d14c8STreehugger Robot   pid_t pid;
74*7c3d14c8STreehugger Robot   pid = fork();
75*7c3d14c8STreehugger Robot   if (pid == 0) { // child
76*7c3d14c8STreehugger Robot     ptrace(PTRACE_TRACEME, 0, NULL, NULL);
77*7c3d14c8STreehugger Robot     execl("/bin/true", "true", NULL);
78*7c3d14c8STreehugger Robot   } else {
79*7c3d14c8STreehugger Robot     wait(NULL);
80*7c3d14c8STreehugger Robot     regs_struct regs;
81*7c3d14c8STreehugger Robot     regs_struct* volatile pregs = &regs;
82*7c3d14c8STreehugger Robot #ifdef ARCH_IOVEC_FOR_GETREGSET
83*7c3d14c8STreehugger Robot     struct iovec regset_io;
84*7c3d14c8STreehugger Robot #endif
85*7c3d14c8STreehugger Robot     int res;
86*7c3d14c8STreehugger Robot 
87*7c3d14c8STreehugger Robot #ifdef POSITIVE
88*7c3d14c8STreehugger Robot     ++pregs;
89*7c3d14c8STreehugger Robot #endif
90*7c3d14c8STreehugger Robot 
91*7c3d14c8STreehugger Robot #ifdef ARCH_IOVEC_FOR_GETREGSET
92*7c3d14c8STreehugger Robot # define __PTRACE_REQUEST  PTRACE_GETREGSET
93*7c3d14c8STreehugger Robot # define __PTRACE_ARGS     (void*)NT_PRSTATUS, (void*)&regset_io
94*7c3d14c8STreehugger Robot     regset_io.iov_base = pregs;
95*7c3d14c8STreehugger Robot     regset_io.iov_len = sizeof(regs_struct);
96*7c3d14c8STreehugger Robot #else
97*7c3d14c8STreehugger Robot # define __PTRACE_REQUEST  PTRACE_GETREGS
98*7c3d14c8STreehugger Robot # define __PTRACE_ARGS     NULL, pregs
99*7c3d14c8STreehugger Robot #endif
100*7c3d14c8STreehugger Robot     res = ptrace((enum __ptrace_request)__PTRACE_REQUEST, pid, __PTRACE_ARGS);
101*7c3d14c8STreehugger Robot     // CHECK: AddressSanitizer: stack-buffer-overflow
102*7c3d14c8STreehugger Robot     // CHECK: {{.*ptrace.cc:}}[[@LINE-2]]
103*7c3d14c8STreehugger Robot     assert(!res);
104*7c3d14c8STreehugger Robot     PRINT_REG_PC(regs);
105*7c3d14c8STreehugger Robot 
106*7c3d14c8STreehugger Robot     fpregs_struct fpregs;
107*7c3d14c8STreehugger Robot #ifdef ARCH_IOVEC_FOR_GETREGSET
108*7c3d14c8STreehugger Robot # define __PTRACE_FPREQUEST  PTRACE_GETREGSET
109*7c3d14c8STreehugger Robot # define __PTRACE_FPARGS     (void*)NT_PRSTATUS, (void*)&regset_io
110*7c3d14c8STreehugger Robot     regset_io.iov_base = &fpregs;
111*7c3d14c8STreehugger Robot     regset_io.iov_len = sizeof(fpregs_struct);
112*7c3d14c8STreehugger Robot     res = ptrace((enum __ptrace_request)PTRACE_GETREGSET, pid, (void*)NT_FPREGSET,
113*7c3d14c8STreehugger Robot                  (void*)&regset_io);
114*7c3d14c8STreehugger Robot #else
115*7c3d14c8STreehugger Robot # define __PTRACE_FPARGS     NULL, &fpregs
116*7c3d14c8STreehugger Robot #endif
117*7c3d14c8STreehugger Robot     res = ptrace((enum __ptrace_request)__PTRACE_FPREQUEST, pid, __PTRACE_FPARGS);
118*7c3d14c8STreehugger Robot     assert(!res);
119*7c3d14c8STreehugger Robot     PRINT_REG_FP(fpregs);
120*7c3d14c8STreehugger Robot 
121*7c3d14c8STreehugger Robot #ifdef __i386__
122*7c3d14c8STreehugger Robot     user_fpxregs_struct fpxregs;
123*7c3d14c8STreehugger Robot     res = ptrace(PTRACE_GETFPXREGS, pid, NULL, &fpxregs);
124*7c3d14c8STreehugger Robot     assert(!res);
125*7c3d14c8STreehugger Robot     printf("%lx\n", (unsigned long)fpxregs.mxcsr);
126*7c3d14c8STreehugger Robot #endif
127*7c3d14c8STreehugger Robot 
128*7c3d14c8STreehugger Robot     ptrace(PTRACE_CONT, pid, NULL, NULL);
129*7c3d14c8STreehugger Robot     wait(NULL);
130*7c3d14c8STreehugger Robot   }
131*7c3d14c8STreehugger Robot   return 0;
132*7c3d14c8STreehugger Robot }
133