在尝试将GDB附加到进程时如何解决"ptrace操作不允许"?

use*_*750 56 c linux debugging gdb strace

我正在尝试使用gdb附加程序,但它返回给我:

附加到进程29139无法附加到进程.如果您的uid与目标进程的uid匹配,请检查/ proc/sys/kernel/yama/ptrace_scope的设置,或以root用户身份再次尝试.有关更多详细信息,请参阅/etc/sysctl.d/10-ptrace.conf ptrace:不允许操作.

edb-debugger返回"无法附加到进程,请检查权限,然后重试."

strace返回"attach:ptrace(PTRACE_ATTACH,...):不允许操作"

我将"kernel.yama.ptrace_scope"1更改为0并将"/ proc/sys/kernel/yama/ptrace_scope"1更改为0并尝试使用以下方法设置"set environment LD_PRELOAD =./ ptrace.so":

#include <stdio.h>
int ptrace(int i, int j, int k, int l) {
    printf(" ptrace(%i, %i, %i, %i), returning -1\n", i, j, k, l);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但它仍然返回相同的错误.我如何将它附加到调试器?

wis*_*cky 130

如果您使用的是Docker,则可能需要以下选项:

docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined
Run Code Online (Sandbox Code Playgroud)

  • 即使问题没有提到Docker,我也因此而来到这里.这解决了我,并感谢你超越了这个问题. (33认同)
  • 在较新的 Docker 版本 18+ 中,不再需要“--security-opt seccomp=unconfined”。 (5认同)
  • 有没有办法在正在运行的 docker 容器上应用此选项? (4认同)
  • 在 docker-compose.yml 中,我只需在容器规范中添加 `cap_add: - SYS_PTRACE` (冒号后有新行)。 (3认同)

jes*_*sup 42

这是由于Linux中的内核强化; 您可以echo 0 > /proc/sys/kernel/yama/ptrace_scope通过修改或禁用此行为来禁用此行为/etc/sysctl.d/10-ptrace.conf

另请参阅Fedora 22中的这篇文章(包含文档的链接)和关于Ubuntu和.的评论主题.

  • 使用sudo和重定向时,可以使用`echo 0 | sudo tee/proc/sys/kernel/yama/ptrace_scope` (9认同)
  • “echo 0 &gt; ...”的变化有多持久?重启后会恢复正常吗?我是在容器中还是在主机中执行此操作? (4认同)
  • 仅当我首先使用sudo -i打开根控制台时,“ echo ...”才有效(由于重定向符号,“ sudo echo ...”不起作用) (3认同)
  • 或者使用 `sudo bash -c "echo 0 &gt; /proc/sys/kernel/yama/ptrace_scope"` (3认同)

Nag*_*gev 19

只是想强调一个相关的答案。假设您是 root 并且您已经完成了:

strace -p 700
Run Code Online (Sandbox Code Playgroud)

并得到:

strace: attach: ptrace(PTRACE_SEIZE, 700): Operation not permitted
Run Code Online (Sandbox Code Playgroud)

查看:

grep TracerPid /proc/700/status
Run Code Online (Sandbox Code Playgroud)

如果您看到类似 的内容TracerPid: 12(即不是 0) ,则表示已在使用ptrace系统调用的程序的 PID 。两者gdbstrace可以使用,并且一次只能有一个处于活动状态。


Doc*_*tor 16

由于我们大多数人都是因为 Docker 问题而来到这里,所以我将添加Kubernetes答案,因为它可能对某人有用......


SYS_PTRACE您必须在 pod 的安全上下文中添加该功能spec.containers.securityContext

       securityContext:
          capabilities:
            add: [ "SYS_PTRACE" ]
Run Code Online (Sandbox Code Playgroud)

securityContext2 个不同的地方有 2 个钥匙。如果它告诉您钥匙无法识别,则说明您放错了钥匙。尝试另一种。

默认情况下,您可能还需要一个 root 用户。因此,在其他安全上下文 ( spec.securityContext) 中添加:

      securityContext:
        runAsUser: 0
        runAsGroup: 0
        fsGroup: 101
Run Code Online (Sandbox Code Playgroud)

仅供参考:0 是根。但我不知道 fsGroup 值。我不在乎我在做什么,但你可能会在乎。

现在你可以这样做:

strace -s 100000 -e write=1  -e trace=write -p 16
Run Code Online (Sandbox Code Playgroud)

您将不会再获得拒绝的许可!

注意:这是潘多拉魔盒。不建议在生产中使用它。


Jur*_*lić 11

我想补充一下,我需要--security-opt apparmor=unconfined@wisbucky提到的选项。这是在Ubuntu 18.04上(Docker客户端和主机)。因此,用于在容器内启用gdb调试的完整调用是:

docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --security-opt apparmor=unconfined

  • @Rafael 已使用完整命令行更新了答案。它现在确实为这个问题提供了一个完全独立的答案。 (3认同)

小智 9

我通过在 Debian 发行版中设置 set Capability 命令以更高的权限运行代码来处理以太网原始套接字。我尝试了上述解决方案:echo 0 > /proc/sys/kernel/yama/ptrace_scope 或者通过修改它,/etc/sysctl.d/10-ptrace.conf但这对我不起作用。

此外,我还尝试在安装目录 (usr/bin/gdb) 中使用 gdb 的设置功能命令,它的工作原理是:/sbin/setcap CAP_SYS_PTRACE=+eip /usr/bin/gdb。请务必使用 root 权限运行此命令。


Max*_*sca 7

没有真正解决上述用例,但我遇到了这个问题:

问题:碰巧我开始使用我的程序sudo,所以在启动gdb时它给了我ptrace: Operation not permitted.

方案:sudo gdb ...

  • 但请注意,如果“echo 3 | ”,“sudo gdb”也将不起作用。sudo tee /proc/sys/kernel/yama/ptrace_scope` (https://www.kernel.org/doc/Documentation/security/Yama.txt),它不会看到你的 `.gdbinit` 脚本。 (2认同)

Zan*_*ynx 0

我不知道你在用 LD_PRELOAD 或 ptrace 函数做什么。

为什么不尝试将 gdb 附加到一个非常简单的程序中呢?制作一个简单地重复打印 Hello 或其他内容的程序,并使用 gdb --pid [hello 程序 PID] 附加到它。

如果这不起作用,那么你确实有问题了。

另一个问题是用户 ID。您正在跟踪的程序是否将自身设置为另一个 UID?如果是,那么除非您使用相同的用户 ID 或者是 root,否则您无法跟踪它。