How to solve "ptrace operation not permitted" when trying to attach GDB to a process?

I'm trying to attach a program with gdb but it returns:

Attaching to process 29139
Could not attach to process. If your uid matches the uid of the target process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Operation not permitted.

gdb-debugger returns "Failed to attach to process, please check privileges and try again."

strace returns "attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted"

I changed "kernel.yama.ptrace_scope" 1 to 0 and /proc/sys/kernel/yama/ptrace_scope 1 to 0 and tried set environment LD_PRELOAD=./ptrace.so with this:

#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;
}

But it still returns the same error. How can I attach it to debuggers?

137444 次浏览

我不知道你在用 LD _ PRELOAD 或者你的 ptrace 函数做什么。

为什么不尝试将 gdb 附加到一个非常简单的程序?创建一个程序,只是重复打印 Hello 或者其他内容,然后使用 gdb —— PID [ Hello program PID ]附加到它。

如果这不起作用,那么你真的有一个问题。

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

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

另请参阅 这篇文章在 Fedora 22(带有文档链接)和 this comment thread about Ubuntu以及。

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

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

Solution: sudo gdb ...

也许有人把这个过程与 gdb 联系起来了。

  • ps -ef | grep gdb

Gdb 不能将同一进程附加两次。

如果您正在使用 Docker,您可能需要以下选项:

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

如果你正在使用 Podman,你可能也需要它的 --cap-add选项:

podman run --cap-add=SYS_PTRACE

我也遇到过同样的问题,也尝试过很多解决方案,但最终我还是找到了解决方案,但是我真的不知道问题出在哪里。首先,我修改了 ptrace _ conf 值并以 root 用户身份登录到 Ubuntu,但问题仍然出现了。但最奇怪的是,广东发展银行向我展示了一条消息:

无法附加到进程。如果 uid 与目标进程的 uid 匹配,请检查/proc/sys/kernel/yama/ptrace _ scope 的设置,或者以 root 用户身份再试一次。
有关详细信息,请参见/etc/sysctl.d/10-ptrace. conf 警告: 进程3767已被进程3755ptrace 跟踪: 操作不允许。

对于 ps 命令终端,没有列出进程3755。

I found the process 3755 in /proc/$pid but I don't understand what was it!!

最后,我删除了试图使用 PTRACE _ ATTACH 系统调用附加 vid gdb 和 tracer c 程序的目标文件(foo.c) ,在另一个文件夹中,我创建了另一个 c 程序并编译了它。

问题解决了,我可以通过 gdb 或 ptrace _ attachsyscall 附加到另一个进程。

(gdb) attach 4416

连接到4416进程

我给4416号处理器发了很多信号。我用 gdb 和 ptrace 对它进行了测试,它们都运行正确。

真的,我不知道问题是什么,但我认为这不是一个错误,在 Ubuntu 的很多网站都提到了它,如 https://askubuntu.com/questions/143561/why-wont-strace-gdb-attach-to-a-process-even-though-im-root

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

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

Jesup's answer is correct; it is due to Linux kernel hardening. In my case, I am using Docker Community for Mac, and in order to do change the flag I must enter the LinuxKit shell using justin cormack's nsenter (ref: https://www.bretfisher.com/docker-for-mac-commands-for-getting-into-local-docker-vm/ ).

docker run -it --rm --privileged --pid=host justincormack/nsenter1

/# cat/etc/问题

欢迎来到 LinuxKit

                    ##         .
## ## ##        ==
## ## ## ## ##    ===
/"""""""""""""""""\___/ ===
{                       /  ===-
\______ O           __/
\    \         __/
\____\_______/

/# cat/proc/sys/kernel/yama/ptrace _ scope

1

/ # echo 0 > /proc/sys/kernel/yama/ptrace_scope

/# 出口

额外信息

如果您希望在接口中进行更改,例如添加 ovs 桥,则必须使用 --privileged而不是 --cap-add NET_ADMIN

sudo docker run -itd --name=testliz --privileged --cap-add=SYS_PTRACE --security-opt seccomp=unconfined ubuntu

如果权限有问题,您可能需要使用 gdbserver。(出于许多原因,我几乎总是在使用 gdb 时使用 gdbserver,不管是否使用 docker。)您需要在 docker 映像中安装 gdbserver (Deb)或 gdb-gdbserver (RH)。在 docker 中运行该程序

$ sudo gdbserver :34567 myprogram arguments

(选择一个端口号,1025-65535)

(gdb) target remote 172.17.0.4:34567

其中,172.17.0.4是在 docker 映像中运行的 /sbin/ip addr list报告的 docker 映像的 IP 地址。这将在 main运行之前的一个点附加。你可以 tb mainc停在 main,或者任何你喜欢的地方。在 cgdb、 emacs、 vim 下运行 gdb,或者甚至在某些 IDE 中运行 gdb。您可以在源代码或构建树中运行 gdb,这样它就知道所有内容的位置。(如果找不到源,请使用 dir命令。)这通常比在 docker 映像中运行它要好得多。

Gdbserver 依赖于 ptrace,因此您还需要执行上面建议的其他操作。

如果部署到其他操作系统或嵌入式目标,可以在那里运行 gdbserver 或 gdb 存根,并以相同的方式运行 gdb,通过实际网络连接,甚至通过串口(/dev/ttyS0)连接。

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

此外,我还尝试在已安装的目录(usr/bin/gdb)中使用 set ability 命令来处理 gdb,它的工作原理是: /sbin/setcap CAP_SYS_PTRACE=+eip /usr/bin/gdb。 请确保使用 root 权限运行此命令。

我要回答这个老问题,因为它是不被接受的,任何其他的答案都没有得到点。真正的答案可能已经写在 /etc/sysctl.d/10-ptrace.conf,因为它是我在 Ubuntu 下的情况。这份文件说:

对于启动需要 PTRACE 的崩溃处理程序的应用程序,例外情况可以 be registered by the debugee by declaring in the segfault handler 具体哪个进程将在调试对象上使用 PTRACE: Prctl (PR _ SET _ PTRACER,debug _ pid,0,0,0) ;

所以只需要做和上面一样的事情: 将 /proc/sys/kernel/yama/ptrace_scope保持为1,并在调试器中添加 prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0);。然后调试器将允许调试器调试它。这不需要 sudo和重启即可工作。

通常,调试器还需要调用 waitpid以避免崩溃后退出,这样调试器就可以找到调试器的 pid。

只是想强调一个相关的 回答。让我们假设你是根,你已经做了:

strace -p 700

and get:

strace: attach: ptrace(PTRACE_SEIZE, 700): Operation not permitted

检查:

grep TracerPid /proc/700/status

如果您看到类似于 TracerPid: 12的内容,即 不是0,那就是已经在使用 追踪系统调用的程序的 PID。gdbstrace都使用它,并且一次只能有一个活动。

如果使用 FreeBSD,编辑 /etc/sysctl.conf,更改行

security.bsd.unprivileged_proc_debug=0

security.bsd.unprivileged_proc_debug=1

然后重启。

由于我们大多数人在这里降落为多克的问题,我将添加 库伯内特的答案,因为它可能会派上用场的人..。


您必须在您的吊舱的安全上下文中添加 SYS_PTRACE功能 at spec.containers.securityContext:

       securityContext:
capabilities:
add: [ "SYS_PTRACE" ]

有两个 securityContext键在两个不同的地方。如果它告诉你密钥没有被识别,那么你就把它放错地方了。试试另一个。

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

      securityContext:
runAsUser: 0
runAsGroup: 0
fsGroup: 101

顺便说一句,0是根。但 fsGroup 的值对我来说是未知的。我不在乎我在做什么,但你可能在乎。

现在你可以做:

strace -s 100000 -e write=1  -e trace=write -p 16

你不会再被拒绝了!

小心: 这是潘多拉的盒子。在生产过程中不推荐使用。