Hi Mike, On 21.12.2015 18:55, Mike Frysinger wrote: > i have a ptrace program that watches for specific syscalls and when > matched, will: > - on entry change the syscall nr to -1 (so the kernel will skip it) > - on exit change the return to -EPERM so the userspace sees a denial > > i have this working on most arches (x86, x86_64, arm, alpha, ia64, etc...). > on parisc, the kernel (using 3.18.7 currently) appears to be wrong. in my > tests, if i don't mess with the syscall nr, i can change the return value > fine (to EPERM or whatever). but the syscall executed which i do not want. > if i change the syscall to -1, then i can't change the return value (so the > child sees ENOSYS), but the kernel still executes the original syscall. > > i have a simple test case attached to show the issue. the code does: > - spawn a child with the parent tracing it > - child will do: > - dupe stderr to another fd > - unlink a file named ".test.flag" > - write a message through the new fd > - close a magic # so the parent knows to start denying > - should see EPERM but it sees ENOSYS > - close the new fd > - should see EPERM but it is closed! > - write to the new fd > - should work, but the fd is closed > - call create on ".test.flag" > - should see EPERM, but the file is created! > - parent will do: > - log the syscalls until child runs close(-12345) > - the parent will then try to deny all close/creat calls > - uses PTRACE_POKEUSER w/PT_GR20 to set syscall to -1 > - uses PTRACE_POKEUSER w/PT_GR28 to set return to -EPERM > > you can run the test case by doing: > $ gcc test.c && ./a.out I agree, something is fishy :-) I did some tests with your testcase. First problem I had was, that compiling failed since it didn't found the asm/offset.h header file. Which one did you used? I know it usually should come with the kernel headers, but there it is asm-offsets.h. If you used debian, which package did you installed? Instead I used asm-offsets.h. First problem: I had to install the 64bit header file. PT_GR20 in this one was much higher than it should be for 32bit userspace. So, I used those defines (taken from the strace source package): #define PT_GR20 (20*4) #define PT_GR26 (26*4) #define PT_GR28 (28*4) #define PT_IAOQ0 (106*4) #define PT_IAOQ1 (107*4) With that I got those output: root@c3000:~# ./a.out a.out: parent waiting for child (pid=1344) to signal: Success a.out: child setting up ... a.out: parent: waiting for exec; status: 0x1a7f a.out: parent: waiting for exec; status: 0x857f a.out: parent: hit exec! a.out: parent: NR: 45 brk a.out: parent: NR: 59 uname a.out: parent: NR: 33 access a.out: parent: NR: 90 mmap a.out: parent: NR: 33 access a.out: parent: NR: 5 open a.out: parent: NR:112 fstat64 a.out: parent: NR: 90 mmap a.out: parent: NR: 6 close a.out: parent: NR: 33 access a.out: parent: NR: 5 open a.out: parent: NR: 3 read a.out: parent: NR:112 fstat64 a.out: parent: NR: 90 mmap a.out: parent: NR: 90 mmap a.out: parent: NR: 90 mmap a.out: parent: NR: 6 close a.out: parent: NR: 90 mmap a.out: parent: NR:125 mprotect a.out: parent: NR: 90 mmap a.out: parent: NR:125 mprotect a.out: parent: NR: 91 munmap a.out: parent: NR: 41 dup a.out: parent: NR: 10 a.out: parent: NR: 4 write child: you should see two of these a.out: parent: NR: 6 close a.out: parent: setting NR to -1 a.out: parent: forcing EPERM child: close marker (should be EPERM): Function not implemented a.out: parent: NR: 4 write a.out: parent: NR: 6 close a.out: parent: setting NR to -1 a.out: parent: forcing EPERM child: real close (should be EPERM): Success a.out: parent: NR: 4 write a.out: parent: NR: 4 write child: write (should be success): Bad file descriptor a.out: parent: NR: 4 write a.out: parent: NR: 8 creat a.out: parent: setting NR to -1 a.out: parent: forcing EPERM child: creat (should be EPERM): Success a.out: parent: NR: 4 write a.out: parent: NR: 33 access child: access (should be ENOENT): Success a.out: parent: NR: 4 write a.out: parent: NR: 10 Seems not like what it should be. I need to look closer at it during the next few days. Regarding on how to get correct 32bit PT_REG #defines/values even on 64bit kernel, maybe the attached patch is a way to go. Helge