簡體   English   中英

嘗試將 GDB 附加到進程時如何解決“不允許 ptrace 操作”?

[英]How to solve “ptrace operation not permitted” when trying to attach GDB to a process?

我試圖用 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\n", i, j, k, l);
    return 0;
}

但它仍然返回相同的錯誤。 如何將其附加到調試器?

如果您使用 Docker,您可能需要以下選項:

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

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

podman run --cap-add=SYS_PTRACE

這是由於 Linux 中的內核強化; 您可以通過echo 0 > /proc/sys/kernel/yama/ptrace_scope或通過在/etc/sysctl.d/10-ptrace.conf修改它來禁用此行為

另請參閱Fedora 22 中有關它的這篇文章(帶有指向文檔的鏈接)以及有關 Ubuntu和 .

我想補充一點,我需要--security-opt apparmor=unconfined以及@wisbucky 提到的選項。 這是在 Ubuntu 18.04(Docker 客戶端和主機)上。 因此,在容器內啟用 gdb 調試的完整調用是:

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

沒有真正解決上述用例,但我遇到了這個問題:

問題:碰巧我用sudo啟動了我的程序,所以在啟動 gdb 時它給了我ptrace: Operation not permitted

解決方案sudo gdb ...

只是想強調一個相關的答案 假設你是 root 並且你已經完成了:

strace -p 700

並得到:

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

檢查:

cat /proc/700/status | grep TracerPid

如果您看到類似TracerPid: 12 ,即不為零,那是已經在使用ptrace系統調用的程序的 PID。 gdbstrace使用它,並且一次只能激活一個。

Jesup 的回答是正確的; 這是由於Linux內核加固。 就我而言,我使用的是 Mac 的 Docker 社區,為了更改標志,我必須使用 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

/ # 退出

也許有人用 gdb 附加了這個過程。

  • ps -ef | grep gdb

不能 gdb 兩次附加相同的進程。

我通過在 Debian 發行版中設置設置功能命令以更高的權限運行我的代碼來處理以太網原始套接字。 我嘗試了上述解決方案: 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 權限運行此命令。

由於我們大多數人都因 Docker 問題來到這里,我將添加Kubernetes答案,因為它可能對某些人有用...


您必須在 pod 的安全上下文中添加SYS_PTRACE功能,位於spec.containers.securityContext

       securityContext:
          capabilities:
            add: [ "SYS_PTRACE" ]

在 2 個不同的地方有 2 個securityContext鍵。 如果它告訴您密鑰未被識別,那么您將其放錯了位置。 試試另一個。

默認情況下,您可能還需要一個 root 用戶。 所以在其他安全上下文( spec.securityContext )中添加:

      securityContext:
        runAsUser: 0
        runAsGroup: 0
        fsGroup: 101

僅供參考:0 是根。 但是我不知道 fsGroup 的值。 對於我在做什么,我不在乎,但你可能會在乎。

現在你可以這樣做:

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

你不會再得到拒絕的許可了!

當心:這是潘多拉盒子。 不推薦在生產中使用它。

如果權限有問題,您可能需要使用 gdbserver。 (出於多種原因,當我使用 gdb、docker 或不使用 gdb 時,我幾乎總是使用 gdbserver。)您需要在 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 鏡像/sbin/ip addr list運行的/sbin/ip addr list報告的 docker 鏡像的 IP 地址。 這將附加在main運行之前的某個點。 你可以tb mainc停在main ,或者你喜歡的任何地方。 在 cgdb、emacs、vim 甚至一些 IDE 中運行 gdb,或者普通。 您可以在源代碼或構建樹中運行 gdb,因此它知道一切都在哪里。 (如果找不到您的源,請使用dir命令。)這通常比在 docker 映像中運行要好得多。

gdbserver 依賴於ptrace ,因此您還需要執行上面建議的其他操作。 --privileged --pid=host對我來說就足夠了。

如果您部署到其他操作系統或嵌入式目標,您可以在那里運行 gdbserver 或 gdb 存根,並以相同的方式運行 gdb,通過真實網絡甚至通過串行端口( /dev/ttyS0 )連接。

我打算回答這個老問題,因為它不被接受,任何其他答案都沒有重點。 真正的答案可能已經寫在/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且無需重啟即可工作。

通常,debugee 還需要調用waitpid以避免崩潰后退出,以便調試器可以找到 debugee 的 pid。

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

為什么不嘗試將 gdb 附加到一個非常簡單的程序? 制作一個簡單地重復打印 Hello 或其他內容的程序,並使用 gdb --pid [hello program PID] 附加到它。

如果這不起作用,那么您確實有問題。

另一個問題是用戶 ID。 您正在跟蹤的程序是否將自身設置為另一個 UID? 如果是,則除非您使用相同的用戶 ID 或者是 root,否則您無法對其進行 ptrace。

我遇到了同樣的問題並嘗試了很多解決方案,但最后,我找到了解決方案,但我真的不知道問題是什么。 首先我修改了 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 但我不明白它是什么!!

最后,我刪除了我嘗試使用 PTRACE_ATTACH 系統調用將其附加到 vid gdb 和 tracer c 程序的目標文件 (foo.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

額外信息

如果您想對接口進行更改,例如添加 ovs 網橋,則必須使用--privileged而不是--cap-add NET_ADMIN

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

如果您使用的是 FreeBSD,請編輯/etc/sysctl.conf ,更改行

security.bsd.unprivileged_proc_debug=0

security.bsd.unprivileged_proc_debug=1

然后重啟。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM