尝试将 GDB 附加到进程时,如何解决“不允许 ptrace 操作”?
- 2024-10-29 08:35:00
- admin 原创
- 76
问题描述:
我正在尝试使用GDB连接到一个程序但它返回:
附加到进程 29139
无法附加到进程。如果您的 uid 与目标进程的 uid 匹配,请检查 /proc/sys/kernel/yama/ptrace_scope 的设置,或以 root 用户身份重试。有关更多详细信息,请参阅 /etc/sysctl.d/10-ptrace.conf
ptrace:操作不允许。
gdb-debugger 返回:
无法附加到进程,请检查权限并重试。
strace 返回:
附加: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
", i, j, k, l);
return 0;
}
但它仍然返回相同的错误。我该如何将其附加到调试器?
解决方案 1:
如果您使用 Docker,您可能需要这些选项:
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined
如果您正在使用 Podman,您可能--cap-add
也需要它的选项:
podman run --cap-add=SYS_PTRACE
解决方案 2:
这是由于 Linux 内核强化所致;您可以通过以下方式禁用此行为echo 0 > /proc/sys/kernel/yama/ptrace_scope
,或者通过修改它来禁用/etc/sysctl.d/10-ptrace.conf
另请参阅有关 Fedora 22 中的这篇文章(包含文档链接)以及有关 Ubuntu 和的这个评论线程。
解决方案 3:
只想强调一个相关的答案。假设您是 root 并且您已完成:
strace -p 700
并得到:
strace: attach: ptrace(PTRACE_SEIZE, 700): Operation not permitted
查看:
grep TracerPid /proc/700/status
如果您看到类似 的内容TracerPid: 12
,即不为 0 ,则这是已在使用ptrace系统调用的程序的 PID 。gdb
和都strace
使用它,并且一次只能有一个处于活动状态。
解决方案 4:
我想补充一点,我需要--security-opt apparmor=unconfined
@wisbucky 提到的选项。这是在 Ubuntu 18.04(Docker 客户端和主机)上。因此,在容器内启用 gdb 调试的完整调用是:
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --security-opt apparmor=unconfined
解决方案 5:
由于我们大多数人来这里是为了解决 Docker 问题,所以我将添加Kubernetes答案,因为它可能会对某些人有用...
SYS_PTRACE
您必须在 pod 的安全上下文中添加该功能spec.containers.securityContext
:
securityContext:
capabilities:
add: [ "SYS_PTRACE" ]
有 2 个securityContext
钥匙位于 2 个不同的地方。如果它告诉您无法识别钥匙,则说明您放错了地方。请尝试另一个。
您可能还需要一个默认的 root 用户。因此,在另一个安全上下文 ( spec.securityContext
) 中添加:
securityContext:
runAsUser: 0
runAsGroup: 0
fsGroup: 101
仅供参考:0 是 root。但 fsGroup 值我不知道。对于我正在做的事情,我不在乎,但你可能在乎。
现在你可以这样做:
strace -s 100000 -e write=1 -e trace=write -p 16
您将不会再收到权限被拒绝的通知!
注意:这是潘多拉魔盒。不建议在生产中使用。
解决方案 6:
并没有真正解决上述用例,但我遇到了这个问题:
问题:我用启动了我的程序sudo
,因此当启动 gdb 时它给了我ptrace: Operation not permitted
。
解决方案:sudo gdb ...
解决方案 7:
我在 Debian 发行版中设置 set capabilities 命令,以更高的权限运行代码来处理以太网原始套接字。我尝试了上述解决方案:echo 0 > /proc/sys/kernel/yama/ptrace_scope
或者通过修改它,/etc/sysctl.d/10-ptrace.conf
但这对我来说不起作用。
此外,我还尝试在安装目录 (usr/bin/gdb) 中使用 set capabilities 命令来设置 gdb 的功能,并且成功了:/sbin/setcap CAP_SYS_PTRACE=+eip /usr/bin/gdb
。请确保以 root 权限运行此命令。
解决方案 8:
Jesup 的回答是正确的;这是由于 Linux 内核强化所致。就我而言,我使用的是 Docker Community for Mac,为了更改标志,我必须使用 justin cormack 的 nsenter 进入 LinuxKit shell(参考: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/issue
欢迎来到 LinuxKit
## . ## ## ## == ## ## ## ## ## === /"""""""""""""""""___/ === { / ===- ______ O __/ __/ ___________/
/# cat /proc/sys/kernel/yama/ptrace_scope
1
/# echo 0>/proc/sys/kernel/yama/ptrace_scope
/ # 出口
解决方案 9:
也许有人已经用 gdb 附加了这个过程。
ps -ef | grep gdb
gdb 无法附加同一个进程两次。
解决方案 10:
我本来要回答这个老问题,因为它不被接受,而且其他任何答案都没有切中要点。真正的答案可能已经写好了,/etc/sysctl.d/10-ptrace.conf
因为这是我在 Ubuntu 下的情况。此文件显示:
对于启动需要 PTRACE 的崩溃处理程序的应用程序,被调试者可以通过在段错误处理程序中具体声明哪个进程将在被调试者上使用 PTRACE 来注册异常:prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0);
因此,只需执行与上述相同的操作:保留/proc/sys/kernel/yama/ptrace_scope
为 1 并添加prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0);
被调试者。然后被调试者将允许调试器对其进行调试。此操作无需sudo
重启即可工作。
通常,被调试者也需要调用waitpid
以避免崩溃后退出,以便调试器可以找到被调试者的 pid。
解决方案 11:
如果你使用的是 FreeBSD,请编辑/etc/sysctl.conf
,将行
security.bsd.unprivileged_proc_debug=0
到
security.bsd.unprivileged_proc_debug=1
然后重新启动。
解决方案 12:
如果权限是个问题,你可能需要使用 gdbserver。(出于多种原因,我使用 gdb 时几乎总是使用 gdbserver,无论是否使用 docker。)你需要在 docker 镜像中安装 gdbserver (Deb) 或 gdb-gdbserver (RH)。使用以下命令在 docker 中运行该程序
$ sudo gdbserver :34567 myprogram arguments
(选择一个端口号,1025-65535)。然后,在主机上的 gdb 中,输入
(gdb) target remote 172.17.0.4:34567
其中,172.17.0.4
docker 镜像的 IP 地址由/sbin/ip addr list
docker 镜像中的 run 报告。这将在运行之前的某个点附加main
。您可以使用tb main
和c
来停止在main
,或任何您喜欢的地方。在 cgdb、emacs、vim 或甚至某些 IDE 中或普通情况下运行 gdb。您可以在源代码或构建树中运行 gdb,这样它就知道所有内容的位置。(如果它找不到您的源代码,请使用命令dir
。)这通常比在 docker 镜像中运行它要好得多。
gdbserver 依赖于ptrace
,因此您还需要执行上面建议的其他操作。--privileged --pid=host
对我来说足够了。
如果部署到其他操作系统或嵌入式目标,则可以在那里运行 gdbserver 或 gdb 存根,并以相同的方式运行 gdb,通过真实网络甚至通过串行端口进行连接(/dev/ttyS0
)。
解决方案 13:
从man prctl(2)
:
PR_SET_PTRACER (since Linux 3.4)
This is meaningful only when the Yama LSM is enabled and in mode 1 ("restricted ptrace", visible via /proc/sys/kernel/yama/ptrace_scope).
When a "ptracer process ID" is passed in arg2, the caller is declaring that the ptracer process can ptrace(2) the calling process as if it
were a direct process ancestor. Each PR_SET_PTRACER operation replaces the previous "ptracer process ID". Employing PR_SET_PTRACER with
arg2 set to 0 clears the caller's "ptracer process ID". If arg2 is PR_SET_PTRACER_ANY, the ptrace restrictions introduced by Yama are ef‐
fectively disabled for the calling process.
为了允许任何进程调试你的程序,你可以添加以下行:
#include <sys/prctl.h>
int main(void)
{
// allows any process to attach
prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...);
// your code
}
如果您不知道调试进程的 PID,这将非常有用。此外,这只会影响程序的安全性,而设置/proc/sys/kernel/yama/ptrace_scope
为0
则会使整个系统变得不那么安全。
解决方案 14:
我不知道您使用 LD_PRELOAD 或 ptrace 函数做什么。
为什么不尝试将 gdb 附加到一个非常简单的程序上呢?制作一个重复打印 Hello 之类的程序,然后使用 gdb --pid [hello program PID] 附加到该程序上。
如果这不起作用那么你确实有问题了。
另一个问题是用户 ID。您正在跟踪的程序是否将自身设置为另一个 UID?如果是,则除非您使用相同的用户 ID 或为 root,否则您无法对其进行 ptrace。
解决方案 15:
我遇到过同样的问题,尝试了很多解决方案,但最终我找到了解决方案,但我真的不知道问题出在哪里。首先,我修改了 ptrace_conf 值并以 root 身份登录 Ubuntu,但问题仍然出现。但最奇怪的是,gdb 向我显示了一条消息,内容是:
`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
warning: process 3767 is already traced by process 3755 ptrace: Operation not permitted.`
使用 ps 命令终端,没有列出进程 3755。
我在 /proc/$pid 中找到了进程 3755,但我不明白它是什么!!
最后,我删除了目标文件(foo.c),并尝试使用 PTRACE_ATTACH 系统调用将其附加到 vid gdb 和 tracer c 程序,然后在另一个文件夹中,我创建了另一个 c 程序并对其进行了编译。
问题已解决,我可以通过 gdb 或 ptrace_attach 系统调用连接到另一个进程。
(gdb) attach 4416
Attaching to process 4416
我向进程 4416 发送了很多信号。我用 gdb 和 ptrace 对其进行了测试,它们都运行正确。
我真的不知道问题是什么,但我认为这不是 Ubuntu 中的一个错误,因为很多网站都提到了它,例如https://askubuntu.com/questions/143561/why-wont-strace-gdb-attach-to-a-process-even-though-im-root
解决方案 16:
额外信息
如果您想要在接口中进行更改(例如添加 ovs 桥),则必须使用--privileged
而不是--cap-add NET_ADMIN
。
sudo docker run -itd --name=testliz --privileged --cap-add=SYS_PTRACE --security-opt seccomp=unconfined ubuntu
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件