Understand and Prevent Linux Fork Bomb
[ for newbies ]

By
Joydeep Bakshi

15-AUG-2009

Copyright and License

Copyright©2009 by Joydeep Bakshi. This material may be distributed only subject to the terms and conditions set forth in the Open Content License, v1.0 or later (the latest version is presently available at opencontent.org ).

Warning

The objective of this guide is to make you familiar with Linux Fork Bombing as well as prevention. Experiment with this in your own box. Realize what a program can do with self replication power. But don't misuse it. I am not liable for such application. 

Function which eats CPU cycles

"Recursive call", "function having recursive capability", "infinite loop" these are the very common terminologies in the programming world. But these innocent tools have deadly power to eat the complete system resources to make the system completely unresponsive.

See the bash script below and don't run it; it makes your system totally unresponsive if it is not protected by anti-fork mechanism. Hardware restart is the only solution in that case.

chainreaction()
{
chainreaction|chainreaction&
};
chainreaction # call the function


The function forks itself  forever, creating a huge number of processes which will utilize every single cycle of the CPU,  causing the system to get stuck.

chainreaction|chainreaction  calls itself and pipes the output to another call of the function hence the function get called two times.

&(backgrounding)- There is no stop condition. Hence if the function runs in foreground; calling function will not complete until the call returns. So the calling function would wait forever and we have the option to kill it and its children. But when running at background the calling function is completed immediately and eat the  resources so quickly that the system becomes unresponsive.

Notice the recursive call is in the background hence the calling process will "die" (in bash but not in C) as soon as it makes the recursive call. If we call the function only once in the recursion, we'll have always one process which will replace its parent, That's why it is called twice here.

The deadly one liner

Make the above script as a one liner

chainreaction() { chainreaction|chainreaction& }; chainreaction

Replace the chainreaction with : (colon) . How does it look like now ?

:(){ :|:& };:

The most deadly Linux Fork Bomb

Prevention

Fork Bomb is a chain reaction tool and it gradually creates new processes. It can only be controlled with restriction on maximum  number of allowed processes. "ulimit" plays a nice role here. "ulimit -a" display all system resources allowed to your shell.

experiment@debian:~$ ulimit -a

core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 16382 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited file locks (-x) unlimited

Fine tune the output to know the maximum process allowed

experiment@debian:~$ ulimit -u

unlimited

Restrict the maximum allowed process to say 200

experiment@debian:~$ ulimit -u 200
experiment@debian:~$ ulimit -u

200

Now execute the one liner

experiment@debian:~$ :(){ :|:& };:

-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
[1] 31979
[1]+ Exit 128 : | :


This is a temporary arrangement to prevent Fork Bomb. Once you log out from your shell; in next login the process limit will again be reset to unlimited. To have a permanent solution put the ulimit restriction in .bashrc or .bash_profile. If you change the ownership of these files to root then the users can't modify it.

system wide solution

Modifying  /etc/security/limits.conf is the permanent (unlike ulimit) approach to fight against Fork Bombing.

Here is an example

admin hard 300
@student soft nproc 100
@student hard nproc 150

User admin is restricted by maximum 300 process at a time. users belong to student group get a warning after crossing the soft value that is 100 process and restricted by hard value that is 150 process as maximum allowed process.  Save the file. logout and login. check by "ulimit -u" to confirm the restriction. Now you can play with fork Bomb.


Fork Bomb Defuser (rexFBD)

rexFBD is a loadable kernel module. It allows to configure the max_forks_per_second and max_tasks_per_user parameters, at the time of loading the module. Programm crossing these restrictions is detected and defused in real time. The uid of the user who started it, as well as the time it was started is logged in /var/log/messages for the system administrator to take action.

http://rexgrep.tripod.com/rexfbdmain.htm

kernel level Prevention

A Linux kernel patch exists,  called grsecurity which enables logging of which user has started a fork bomb.

http://en.wikipedia.org/wiki/Grsecurity
 
Z Shell anti-fork

The following short Z Shell code can destroy fork bomb in about a minute

while (sleep 100 &!) do; done

The sleep is introduced to make processes sleep for a short period of time, and due to the delay there are less fork-bombs. Eventually the sleep processes fill up the process table themselves and the fork bombs die off. Once the process table is full off sleep processes the while loop can be killed, and the sleep processes will die once their sleep time is up. Problem solved.


Side note

perl  based fork bomb
perl -e "fork while fork"&

Here is one for windows
       :bomb
        start %0
        %0|%0
        goto bomb


Feedback

Comments, corrections and suggestions are always welcome. email.gif

INDEX | HOME
Copyright© 2009, Joydeep Bakshi