
我設定了測試VM來測試fork炸彈的效果。所以我為使用者編輯limits.conf
如下:root
root hard nproc 512
現在我像這樣扔下一個叉子炸彈:
:(){ :|:& };:
此後,過了一段時間(我相信需要達到 512 限制),出現以下錯誤:
這種情況持續不斷。有什麼辦法可以在不重新啟動機器的情況下停止此操作嗎?
答案1
有什麼辦法可以在不重新啟動機器的情況下停止此操作嗎?
這並非完全不可能,您可以透過運氣來做到這一點——也就是說,您可以在另一個進程產生之前設法殺死所有進程。1 但你必須非常非常幸運,所以這不是一個可靠或值得的努力[也許 slm 比我幸運,哈哈-說實話,我還沒那麼努力]。如果您考慮優先級,您的機會可能會提高(請參閱參考資料man nice
),儘管我懷疑這也會影響叉子炸彈的功效。
更好的想法可能是使用超時的方法。有關 C 語言的範例,請參閱註腳 5我的回答在這裡。2 您可以使用 shell 腳本執行相同的操作,儘管不會那麼短:(){ :|:& };:
:
#!/bin/bash
export fbomb_duration=$1
export fbomb_start=$(date +%s)
go () {
now=$(date +%s)
if [[ $(($now-$fbomb_start)) -gt $fbomb_duration ]]
then exit 0;
fi
go &
}
while ((1)); do
go
done
使用一個參數執行該操作,秒數。在那之後所有的分叉都會消失。
1事實上,如果內核 OOM 殺手運氣好的話,最終它可能會自行發生。但不要屏住呼吸。
2用於限制特定炸彈的方法(透過設定vm.overcommit_memory=2
)幾乎肯定不會在一般情況下起作用,但您可以嘗試。我不是,因為我想讓我的系統暫時保持運作;)
答案2
在製定這個問題的答案時,標題為:叉子炸彈上的 fork() 在哪裡:(){ :|: & };:?,我組裝了一個我稱之為導火線延遲叉炸彈的東西,更容易殺死。
此外,在開發這個答案時,我經常能夠透過終止所有進程來阻止叉子炸彈。它比我預想的更容易、更可重複。
使用的方法
自從我寫這個答案以來已經有一段時間了,所以我現在不能 100% 確定,但我突然想到我正在使用這種方法:
$ pkill -f :
它會停滯一段時間等待進程,但最終它能夠運作。另外,我會在啟動 fork 炸彈之前記下父進程 ID,也會這樣做:
$ pkill -P <PPID>
這是運行 fork 炸彈的父進程 ID (PPID)。該方法將關閉所有子進程,這將導致它們全部級聯並死亡。
答案3
我相信你可以按照答案中的建議來操作這裡假設您有權存取 shell。
killall -STOP -u user1
killall -KILL -u user1