11

我正在调试一个使用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二进制文件本身,但无济于事。我这样做了(正如手册页所记录的那样,“ i”标志可能允许被调试者从调试器继承能力。

是否有一些琐碎的事情我错过了,或者这真的不能完成吗?

4

6 回答 6

17

我遇到了同样的问题,一开始我认为和上面一样,也许 gdb 由于安全原因而忽略了可执行文件的功能。但是,阅读源代码,甚至在调试打开的 ext2fs-prog 时使用 eclipse 调试 gdb 本身/dev/sda1,我意识到:

  1. gdb 与任何其他程序没有什么特别之处。(就像在矩阵中一样,即使是代理人本身,他们也遵守相同的物理定律、重力等,只是他们都是守门人。)
  2. gdb 不是被调试可执行文件的父进程,而是祖父进程。
  3. 调试的可执行文件的真正父进程是“shell”,即/bin/bash在我的情况下。

因此,解决方案非常简单,除了添加cap_net_admin,cap_net_raw+eip到 gdb 之外,您还可以将其应用于您的 shell。IEsetcap cap_net_admin,cap_net_raw+eip /bin/bash

您还必须对 gdb 执行此操作的原因是因为 gdb 是/bin/bash创建调试进程之前的父进程。

gdb 中真正的可执行命令行如下所示:

/bin/bash exec /my/executable/program/path

这是 gdb 中 vfork 的参数。

于 2014-08-18T14:03:53.290 回答
4

对于那些有同样问题的人,您可以通过使用 sudo 执行 gdb 来绕过这个问题。

于 2013-02-13T13:48:41.603 回答
3

不久前,我确实遇到了同样的问题。我的猜测是,运行带有附加功能的调试程序是一个安全问题。

您的程序比运行它的用户拥有更多权限。使用调试器,用户可以操纵程序的执行。因此,如果程序在具有额外特权的调试器下运行,则用户可以将这些特权用于程序打算使用它们的其他目的。这将是一个严重的安全漏洞,因为用户一开始就没有权限。

于 2010-12-05T08:08:29.023 回答
2

对于那些通过 IDE 运行 GDB 的人来说,sudo-ing GDB(如@Stéphane J. 的回答)可能是不可能的。在这种情况下,您可以运行:

sudo gdbserver localhost:12345 /path/to/application

然后将您的 IDE 的 GDB 实例附加到该(本地)GDBServer。

对于 Eclipse CDT,这意味着创建一个新的“C/C++ 远程应用程序”调试配置,然后在 Debugger > Connection 选项卡下,输入 TCP / localhost / 12345(或您在上面选择的任何端口)。这使您可以在 Eclipse 中进行调试,同时您的应用程序具有特权访问权限。

于 2018-01-04T23:43:24.173 回答
2

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

set startup-with-shell off
于 2020-05-15T04:32:28.680 回答
0

好的,所以我对此有点挣扎,所以我想我会结合答案和总结。

简单的解决方案就是sudo gdb按照建议进行,但要小心一点。您在这里所做的是以 root 身份运行调试程序。这很可能会导致它的运行方式与您从命令行以普通用户身份运行时不同。可能有点混乱。并不是说我会掉进这个陷阱……哎呀。

sudo如果您以 root 身份运行调试程序,并且如果调试程序setuid设置了位,这将很好。但是,如果调试的程序使用 POSIX 功能 ( setcap/ getcap) 运行,那么您需要按照 Nick Huang 的建议在 bash 和 gdb 中镜像这些更细化的权限,而不是仅仅使用“sudo”强制权限。

做任何其他事情都可能会导致你进入极端学习的坏境地。

于 2020-01-14T20:31:21.840 回答