如何阻止 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

相关内容