Process
為什麼基於 unshare 的殺戮只能與 –fork 一起可靠地工作?
從這個答案中我們了解到,您可以使用 Linux PID 命名空間通過
unshare -p
.這是我不明白的問題:
- 它僅在我使用
-f
/--fork
選項取消共享時才有效。unshare -fp -- bash -c "watch /bin/sleep 10000 && echo hi"
當我執行它時,它
kill -9
的 PIDbash
,然後 watch,sleep 等都死了,正如我所願。
- 但是當我沒有使用它時
-f
:unshare -p -- bash -c "watch /bin/sleep 10000 && echo hi"
和
kill -9
bash 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 unshare說
CLONE_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"