Created attachment 924221 [details]
Simple C program to bind to a port, can be used for reproducing problem
Description of problem:
When a process is run under ptrace, the capabilities masks are not honored. There is no mention of such a restriction on the capabilties(7) man page, and it causes problems for services such as Upstart when attempting to trace a daemon that forks initially, to obtain the PID to wait for.
Version-Release number of selected component (if applicable):
Steps to Reproduce:
The attached C program will bind to the port specified on the command line, and report success of failure. It will sleep for a while after the bind (if it succeeds) to allow process inspection.
1. Compile the program, and run it as non-root, passing a privileged port on the command line (e.g. 443), and observe that it fails as expected.
2. As root, run:
# setcap 'cap_net_bind_service+iep' PROGRAM
3. Run the program as non-root, and observe that it succeeds.
4. strace the program as non-root, and observe that it fails.
For steps 3 and 4, if you cat /proc/PID/status while the process is running (e.g. while it is sleeping after the bind), you'll notice that for step 3:
While for step 4:
This demonstrates that somehow ptrace has managed to clear the capabilities sets for Permitted and Effective. Note I do not understand why CapInh is zero in step 3. This does not match the behavior I expect from the man page.
Bind fails in step 4
Bind should succeed whether or not it is run under ptrace, if capability is set
Oleg, any ideas on this one?
Off the top of my head, I would think the program being ptraced would inherit the capabilities of the parent that started it. The strace program isn't going to have those capabilities set, so it would make sense the application it starts doesn't. Otherwise it seems it would be a trivial thing to exploit to gain additional priviledges as a normal user.
(In reply to Josh Boyer from comment #1)
> Oleg, any ideas on this one?
This looks correct.
Lets forget about capabilities for the moment. strace suid-binary won't
work, and for obvious reasons. The same is true for capabilities, it is
not safe to allow the unprivileged user to control the application which
runs with the raised privileges.
If /usr/bin/strace has CAP_SYS_PTRACE it should probably work, but I did
not verify and I never understood in details how capabilities work.
NOTABUG, I think.