gdb appears to ignore executable capabilities
-
08-10-2019 - |
Question
I am debugging a program that makes use of libnetfilter_queue
. The documentation states that a userspace queue-handling application needs the CAP_NET_ADMIN
capability to function. I have done this using the setcap
utility as follows:
$ sudo setcap cap_net_raw,cap_net_admin=eip ./a.out
I have verified that the capabilities are applied correctly as a) the program works and b) getcap
returns the following output:
$ getcap ./a.out
./a.out = cap_net_admin,cap_net_raw+eip
However, when I attempt to debug this program using gdb
(e.g. $ gdb ./a.out
) from the command line, it fails on account of not having the correct permissions set. The debugging functionality of gdb
works perfectly otherwise and debugs as per normal.
I have even attempted to apply these capabilities to the gdb
binary itself to no avail. I did this as it seemed (as documented by the manpages that the "i
" flag might allowed the debugee to inherit the capability from the debugger.
Is there something trivial I am missing or can this really not be done?
Solution
A while ago I did run into the same problem. My guess is that running the debugged program with the additional capabilities is a security issue.
Your program has more privileges than the user that runs it. With a debugger a user can manipulate the execution of the program. So if the program runs under the debugger with the extra privileges then the user could use these privileges for other purposes than for which the program intended to use them. This would be a serious security hole, because the user does not have the privileges in the first place.
OTHER TIPS
I run into same problem and at beginning I thought the same as above that maybe gdb is ignoring the executable's capability due to security reason. However, reading source code and even using eclipse debugging gdb itself when it is debugging my ext2fs-prog which opens /dev/sda1
, I realize that:
- gdb is no special as any other program. (Just like it is in the matrix, even the agents themselves they obey the same physical law, gravity etc, except that they are all door-keepers.)
- gdb is not the parent process of debugged executable, instead it is grand father.
- The true parent process of debugged executable is "shell", i.e.
/bin/bash
in my case.
So, the solution is very simple, apart from adding cap_net_admin,cap_net_raw+eip
to gdb, you have also apply this to your shell. i.e. setcap cap_net_admin,cap_net_raw+eip /bin/bash
The reason that you have also to do this to gdb is because gdb is parent process of /bin/bash
before create debugged process.
The true executable command line inside gdb is like following:
/bin/bash exec /my/executable/program/path
And this is parameter to vfork inside gdb.
For those who have the same problem, you can bypass this one by executing gdb with sudo.
For those running GDB through an IDE, sudo-ing GDB (as in @Stéphane J.'s answer) may not be possible. In this case, you can run:
sudo gdbserver localhost:12345 /path/to/application
and then attach your IDE's GDB instance to that (local) GDBServer.
In the case of Eclipse CDT, this means making a new 'C/C++ Remote Application' debug configuration, then under the Debugger > Connection tab, entering TCP / localhost / 12345 (or whatever port you chose above). This lets you debug within Eclipse, whilst your application has privileged access.