我正在调试一个使用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
”标志可能允许debugee继承调试器的功能。
有什么微不足道的我遗失或者这真的不能做到吗?
前段时间我遇到了同样的问题。我的猜测是,运行带有附加功能的调试程序是一个安全问题。
您的程序具有比运行它的用户更多的权限。使用调试器,用户可以操纵程序的执行。因此,如果程序在具有额外特权的调试器下运行,则用户可以将这些特权用于除程序打算使用它们之外的其他目的。这将是一个严重的安全漏洞,因为用户首先没有权限。
我遇到了同样的问题,一开始我就像上面一样认为,由于安全原因,gdb可能会忽略可执行文件的功能。但是,在调试我的ext2fs-prog打开/dev/sda1
时,阅读源代码甚至使用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中真正的可执行命令行如下所示:
/bin/bash exec /my/executable/program/path
这是gdb内vfork的参数。
对于那些有相同问题的人,可以通过使用sudo执行gdb来绕过这个问题。
对于那些通过IDE运行GDB的人来说,可能无法使用GDB(如@StéphaneJ。的答案)。在这种情况下,您可以运行:
sudo gdbserver localhost:12345 /path/to/application
然后将IDE的GDB实例附加到该(本地)GDBServer。
对于Eclipse CDT,这意味着要进行新的“C / C ++远程应用程序”调试配置,然后在“调试器”>“连接”选项卡下输入TCP / localhost / 12345(或上面选择的任何端口)。这使您可以在Eclipse中进行调试,同时您的应用程序具有特权访问权限。