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

2024-10-29 08:35:00
admin
原创
75
摘要:问题描述:我正在尝试使用GDB连接到一个程序但它返回:附加到进程 29139 无法附加到进程。如果您的 uid 与目标进程的 uid 匹配,请检查 /proc/sys/kernel/yama/ptrace_scope 的设置,或以 root 用户身份重试。有关更多详细信息,请参阅 /etc/sysctl.d...

问题描述:

我正在尝试使用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_scope1 改为 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.4docker 镜像的 IP 地址由/sbin/ip addr listdocker 镜像中的 run 报告。这将在运行之前的某个点附加main。您可以使用tb mainc来停止在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_scope0则会使整个系统变得不那么安全。

解决方案 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
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用