Fork 炸弹

在 Linux 的 shell 脚本中,流传着一个很有意思,当然也是相当危险的脚本段,俗称 Fork 炸弹(Fork Bomb)。如下:

:(){ :|:& };:

Fork 炸弹会以极快的速度创建大量的进程(进程数以指数式增长),以此消耗系统分配给予的进程可用空间,使进程表饱和。进程表饱和后,就无法运行新程序,除非终止进程表中的某一个进程;但被终止的进程,又会立刻被 Fork 炸弹探测到并被占用,导致仍然无法运行新的程序。Fork 炸弹生成的子程序在消耗进程表空间的同时,也会占用 CPU 和内存,从而导致系统与现有进程运行速度放缓,响应时间也随之大幅增加,以致于无法完成正常的任务,从而使系统的正常运作受到严重影响。那么,这个由 13 个字符(包括两个空格字符)组成的所谓 Fork 炸弹,为何会有如此大的威力呢?

我们来看看这几个字符都干了些什么?

:() # 定义函数,函数名为":",不接受参数
{ # 函数体开始标识
: # 调用函数":",即调用自身。可见是一种递归调用。
| # 用管线(pipe)将结果输出至 ... (由于有管线操作,因此会 fork 一个新的进程处理)
: # 在新的进程中的调用函数":"。":|:"表示每次调用函数":",都会产生两份拷贝
& # 调用间脱钩,以使最初的":"函数被关闭后,其所调用的两个":"函数还能继续执行
} # 函数体结束标识
; # ":"函数定义结束后将要进行的操作 ...
: # 调用":"函数,即引爆fork炸弹

这么一解释,发现还真是那么可怕!好在 Fork 炸弹本身并没有传染性,只要重启下系统也就恢复了。

那么,我们有没有可能防范 Fork 炸弹的攻击呢?答案是显然的。Fork 炸弹的攻击方式是不断占用进程数来瘫痪系统,那么,如果我们能够限制单个用户的进程数创建上限,就不至于被 Fork 炸弹瘫痪了。在 Linux 系统上,可以通过 ulimit 这个指令来实现。例如,

$ ulimit 200

表示为当前用户创建200个进程上限。

留下评论