I found some surprising behavior on Ubuntu 14.04 when using strace on an executable, which I do not have read permission on. I wonder if this is a bug, or if some standard mandates this obscure behavior.

First let's see what happens when I start an ordinary executable in the background and attach to it. As expected this works:

$ /bin/sleep 100 &
[2] 8078
$ strace -p 8078
Process 8078 attached
restart_syscall(<... resuming interrupted call ...>

Next I try with an executable, which I have no read permissions on:

---x--x--x 1 root root 26280 Sep  3 09:37 sleep*

Attaching to this running process is not permitted:

$ ./sleep 100 &
[1] 8089
$ strace -p 8089
strace: attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted

This is also what I would expect. Granting execute permission without read permission wouldn't do much good, if I could simply attach a debugger to the process and effectively have read permissions on the executable that way.

But if I start the executable under an already traced process, I am permitted to do so:

$ strace ./sleep 100
execve("./sleep", ["./sleep", "100"], [/* 69 vars */]) = 0
brk(0)                                  = 0x9b7a000

This is unexpected for me. Is this a security bug, or is it a feature mandated by a standard?

  • 3
    @StéphaneChazelas: The point is that he can ptrace it, by simply using it as argument to strace. The root cause seems to be that on execve calls, read permissions of the executed file are not checked again if the process is already traced. His question is whether that is a security bug or a mandated feature (if the latter, I'd still consider it a security bug, just a security bug of the specification). – celtschk Sep 3 '14 at 9:05
  • @celtschk, sorry, I read the question too quickly. – Stéphane Chazelas Sep 3 '14 at 9:15
  • 1
    The EPERM seems to come from get_dumpable() (used also to check whether core dumping is allowed, thus "dumpable") called from __ptrace_may_access() called from ptrace_attach() on kernel/ptrace.c. – ninjalj Sep 3 '14 at 10:06
  • When a program is running, will sufficient information be available to the debugger to generate a runnable executable containing its code, or will the program loader discard things like relocation fixups which would be needed to make a program actually work? – supercat Sep 3 '14 at 15:51
  • @supercat As far as I know, the debugger has access to single step through all the user mode code being executed, including the relocation code. With that level of access it shouldn't be too difficult to reproduce a working executable. – kasperd Sep 3 '14 at 16:11

This is not an answer, rather a collection of links and thoughts in case someone else would like to study as well. Because this is quite an interesting thing.

Related answer on Unix&Linux mentioning it is (or was, can't test with vanilla kernel right now) possible to dump read only binaries this way.

Grsecurity was trying to fix this config option and the patch itself (altough it may have changed since)

This commit really makes it seem that, kernel developers really care only about dumping suid binaries.

But actually from this line I'd guess kernel wants to prevent dumping unreadable binaries regardles of SUID status. And this line suggests that binaries which are not dumpable should not be traceable.

So at first sight it seems you have found a bug in kernel with security implications. But I am no kernel developer, so I can not say for sure. I would ask on LKML.

Edit: one more finding, with regards to debugger, mentioned in comments to original post - from quick stracing (again) it seems to me, that gdb uses the traced binaries and /proc/<pid>/mem. Once the running binary is not readable, cat /proc/<pid>/mem returns EPERM. If the binary is readable, it returns EIO. (Tested this on Ubuntu 14.10, which runs several security patches, so this might be different from vanilla kernel. Again I do not have vanilla kernel running anywhere handy :()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.