gdb似乎忽略了可执行功能

问题描述 投票:7回答:4

我正在调试一个使用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继承调试器的功能。

有什么微不足道的我遗失或者这真的不能做到吗?

linux network-programming gdb sniffing linux-capabilities
4个回答
3
投票

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

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


9
投票

我遇到了同样的问题,一开始我就像上面一样认为,由于安全原因,gdb可能会忽略可执行文件的功能。但是,在调试我的ext2fs-prog打开/dev/sda1时,阅读源代码甚至使用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的参数。


3
投票

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


2
投票

对于那些通过IDE运行GDB的人来说,可能无法使用GDB(如@StéphaneJ。的答案)。在这种情况下,您可以运行:

sudo gdbserver localhost:12345 /path/to/application

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

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

© www.soinside.com 2019 - 2024. All rights reserved.