gdb 似乎忽略了可执行功能

发布于 2024-10-05 16:32:26 字数 725 浏览 2 评论 0原文

我正在调试一个使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

酷遇一生 2024-10-12 16:32:26

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

  1. gdb 与其他程序一样没有什么特别之处。 (就像在矩阵中一样,即使是代理本身,它们也遵守相同的物理定律、重力等,只是它们都是看门人。)
  2. gdb 不是调试可执行文件的父进程,而是祖父进程。
  3. 被调试的可执行文件的真正父进程是“shell”,在我的例子中即 /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 的参数。

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:

  1. 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.)
  2. gdb is not the parent process of debugged executable, instead it is grand father.
  3. 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.

野侃 2024-10-12 16:32:26

我使用了 @NickHuang 的解决方案,直到其中一个系统更新破坏了 systemd 服务(bash 上的功能太多,systemd 无法启动它或类似的功能)。改为单独保留 bash,而是将命令传递给 gdb 以直接调用可执行文件。命令是

set startup-with-shell off

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
感受沵的脚步 2024-10-12 16:32:26

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

For those who have the same problem, you can bypass this one by executing gdb with sudo.

你又不是我 2024-10-12 16:32:26

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

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

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.

说不完的你爱 2024-10-12 16:32:26

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

sudo gdbserver localhost:12345 /path/to/application

然后将 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:

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.

静水深流 2024-10-12 16:32:26

好吧,所以我在这个问题上遇到了一些困难,所以我想我应该结合答案并进行总结。

简单的解决方案就是按照建议使用 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 the setuid 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文