如何阻止 Fork Bomb 記憶體不足錯誤 - RHEL 6

如何阻止 Fork Bomb 記憶體不足錯誤 - RHEL 6

我設定了測試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

相關內容