gdb 似乎忽略了可执行功能
我正在调试一个使用 libnetfilter_queue 的程序。该文档指出,用户空间队列处理应用程序需要 CAP_NET_ADMIN 功能才能运行。我已经使用 setcap
实用程序完成了此操作,如下所示:
$ sudo setcap cap_net_raw,cap_net_admin=eip ./a.out
我已验证这些功能是否正确应用,因为 a) 程序正常工作,b) getcap
返回以下输出:
$ getcap ./a.out
./a.out = cap_net_admin,cap_net_raw+eip
但是,当我尝试从命令行使用 gdb
(例如 $ gdb ./a.out
)调试此程序时,由于没有设置正确的权限而失败。否则,gdb
的调试功能可以正常工作并正常调试。
我什至尝试将这些功能应用到 gdb 二进制文件本身,但没有成功。我这样做了,因为它看起来(如 记录的) manpages 指出“i
”标志可能允许调试者从调试器继承功能。
我是否遗漏了一些琐碎的事情,或者这真的不能完成?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我遇到了同样的问题,一开始我的想法与上面相同,也许 gdb 由于安全原因而忽略了可执行文件的功能。然而,阅读源代码,甚至在调试打开
/dev/sda1
的 ext2fs-prog 时使用 eclipse 调试 gdb 本身,我意识到:/bin/bash
。因此,解决方案非常简单,除了将
cap_net_admin,cap_net_raw+eip
添加到 gdb 之外,还将其应用到您的 shell 中。即setcap cap_net_admin,cap_net_raw+eip /bin/bash
您还必须对 gdb 执行此操作的原因是因为 gdb 在创建调试之前是
/bin/bash
的父进程过程。gdb 中真正的可执行命令行如下所示:
这是 gdb 中 vfork 的参数。
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:/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:
And this is parameter to vfork inside gdb.
我使用了 @NickHuang 的解决方案,直到其中一个系统更新破坏了 systemd 服务(bash 上的功能太多,systemd 无法启动它或类似的功能)。改为单独保留 bash,而是将命令传递给 gdb 以直接调用可执行文件。命令是
I used @NickHuang's solution until, with one of system updates, it broke systemd services (too much capabilities on bash for systemd to start it or some such). Switched to leaving bash alone and instead pass a command to gdb to invoke the executable directly. The command is
对于有同样问题的人,可以通过使用 sudo 执行 gdb 来绕过这一问题。
For those who have the same problem, you can bypass this one by executing gdb with sudo.
不久前我也遇到了同样的问题。我的猜测是,运行具有附加功能的调试程序是一个安全问题。
您的程序比运行它的用户拥有更多的权限。使用调试器,用户可以操纵程序的执行。因此,如果程序在具有额外权限的调试器下运行,那么用户可以将这些权限用于程序打算使用它们之外的其他目的。这将是一个严重的安全漏洞,因为用户一开始就没有权限。
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.
对于那些通过 IDE 运行 GDB 的人来说,sudo-ing GDB(如 @Stéphane J. 的答案)可能是不可能的。在这种情况下,您可以运行:
然后将 IDE 的 GDB 实例附加到该(本地)GDBServer。
对于 Eclipse CDT,这意味着创建一个新的“C/C++ 远程应用程序”调试配置,然后在“调试器”>“调试器”下进行配置。连接选项卡,输入 TCP / localhost / 12345 (或您在上面选择的任何端口)。这使您可以在 Eclipse 中进行调试,同时您的应用程序具有特权访问权限。
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:
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.
好吧,所以我在这个问题上遇到了一些困难,所以我想我应该结合答案并进行总结。
简单的解决方案就是按照建议使用 sudo gdb ,但要小心一点。您在这里所做的是以 root 身份运行调试后的程序。这很可能会导致它的运行方式与以普通用户身份从命令行运行它时不同。可能有点混乱。并不是说我会陷入这个陷阱……哎呀。
如果您使用
sudo
以 root 身份运行被调试程序,或者被调试程序设置了setuid
位,那就没问题了。但是,如果调试的程序使用 POSIX 功能(setcap
/getcap
)运行,那么您需要按照 Nick Huang 的建议,在 bash 和 gdb 中镜像这些更细粒度的权限,而不仅仅是暴力使用“sudo”强制权限。做任何其他事情可能会导致你陷入极限学习的糟糕境地。
OK, so I struggled a bit with this so I thought I'd combine answers and summarise.
The easy solution is just to
sudo gdb
as suggested but just be a bit careful. What you're doing here is running the debugged program as root. This may well cause it to operate differently than when you run it from the command line as a normal user. Could be a bit confusing. Not that I would EVER fall into this trap... Oopsies.This will be fine if you're running the debugged program as root with
sudo
OR if the debugged program has thesetuid
bit set. But if the debugged program is running with POSIX capabilities (setcap
/getcap
) then you need to mirror these more granular permissions in bash and gdb as Nick Huang suggested rather than just brute forcing permissions with 'sudo'.Doing anything else may lead you to a bad place of extreme learning.