Process

為什麼基於 unshare 的殺戮只能與 –fork 一起可靠地工作?

  • June 17, 2018

這個答案中我們了解到,您可以使用 Linux PID 命名空間通過unshare -p.

這是我不明白的問題:

  • 它僅在我使用-f/--fork選項取消共享時才有效。
unshare -fp -- bash -c "watch /bin/sleep 10000 && echo hi"

當我執行它時,它kill -9的 PID bash,然後 watch,sleep 等都死了,正如我所願。

  • 但是當我沒有使用它時-f
unshare -p -- bash -c "watch /bin/sleep 10000 && echo hi"

kill -9bash PID,然後將其重新設置watch為 PID 1(在我的 Ubuntu 上是 systemd),所以我沒有殺死所有孩子的預期效果。

問題:

  • 為什麼--fork需要達到預期的效果?為什麼不unshare使用exec()fork 是不夠的?
  • 有解決方法嗎?如果我可以方便地發送到通過開始殺死它下面的所有東西而kill -9創建的 PID,我會更喜歡。unshare但是當我使用 時--fork,殺死我開始時返回的 pidunshare將簡單地殺死unshare並重新設置bash為 PID 1,因為unshare它不在我的 PID 命名空間中。

請注意,這&& echo hi是必需的,因為如果您只向 發出一個命令bash -c,它就會執行exec(),因此 bash 程序已經消失(被替換)並且您無法殺死它的 PID。

正如這個有用的答案-n中所描述的, ( )的影響unshare(CLONE_NEWPID)只對第一個子程序分叉起作用。

特別是,man 2 unshareCLONE_NEWPID

取消共享 PID 命名空間,以便呼叫程序為其子程序擁有一個新的 PID 命名空間,該命名空間不與任何先前存在的程序共享。

呼叫程序不會移動到新的命名空間中。

呼叫程序創建的第一個子程序的程序 ID 為 1,並將init(1)在新命名空間中扮演角色。


修補unshare以使殺戮可靠地工作

自從問了我的問題後,在過去的幾個小時裡,我已經寫了一個更新檔到util-linux這里拉取請求),它添加了一個--kill-child標誌到unshare.

**編輯:**現在已合併並作為 util-linux 的一部分發布v2.32

你可以像這樣使用它:

unshare -fp --kill-child -- bash -c "watch /bin/sleep 10000 && echo hi"

並且殺死unshare將隨著加速而將整個程序樹摧毀。

沒有root

如果您的核心通過傳遞標誌root啟用了使用者命名空間( ),您甚至可以在沒有特權的情況下使用它:CONFIG_USER_NS=y``-U

unshare -Ufp --kill-child -- bash -c "watch /bin/sleep 10000 && echo hi"

引用自:https://unix.stackexchange.com/questions/393210