1. Overview

In this tutorial, we’ll understand how a Bash fork bomb works and how to prevent it.

2. How It Works

A Bash fork bomb is a sequence of Bash commands running a neverending recursive function. This results in an out-of-control consumption of system resources eventually making the system become slow, unresponsive, or even crash.

The most common way to create a fork bomb is to define a function that creates a child process of the same function in the background:

# Warning: don't run this command on your computer unless you want it to crash.
$ :(){ :|: & };:

This is the definition of a function named “:” that will execute itself, returning the result with a pipe to another instance of itself executed in the background. The function is then run for the first time with the “:”  at the end of the line.

We can also write this Bash fork bomb in a more human-readable way:

forkbomb() { 
    forkbomb | forkbomb & 
};forkbomb

We can see that this function is calling itself twice every time and it has no way to terminate itself. This will eventually result in a system crash.

2.1. On systemd Linux Distros

For Linux distros using systemd, the methods above may result in the opening of a lot of processes. However, the system won’t crash and after some time it automatically closes all processes.

This is because systemd creates a cgroup for each user which sets limits on system resources such as the total number of processes, RAM usage, etc. It’s a more modern layer of resource limiting than ulimit which uses the getrlimit() system call.

Let’s see the current and maximum number of processes and threads that are allowed within our current cgroup:

$ systemctl status user-$UID.slice
user-1000.slice - User Slice of UID 1000
     Loaded: loaded
    Drop-In: /usr/lib/systemd/system/user-.slice.d
             └─10-defaults.conf
     Active: active since Mon 2022-11-14 21:43:19 EAT; 1 day 17h ago
       Docs: man:[email protected](5)
      Tasks: 2161 (limit: 30975)
     Memory: 9.8G
     CGroup: /user.slice/user-1000.slice

By default, the total number of tasks that systemd allows for each user is usually 33% of the system-wide total.

Let’s find out the system-wide total:

$ sysctl kernel.threads-max
kernel.threads-max = 93866

To crash a system running on systemd, we need to reduce the limit on the number of processes.

Here’s how we can do this for systemd version 239 and later:

$ systemctl [--runtime] set-property user-$UID.slice TasksMax=2500

Here, we’re setting the maximum number of tasks to 2500. Running the fork bomb after this change will crash the system.

Alternatively, for systemd version 238 and earlier, the user default is set via UserTasksMax= in the /etc/systemd/logind.conf directory.

We can open it with the nano editor and then change the limit:

$ nano /etc/systemd/logind.conf

Changing the value generally requires a reboot to effect the changes.

3. Mitigation Techniques

Fork bombs are not unique to Bash — many other languages can implement them.

There are mainly two reasons a fork bomb can happen:

  • a software bug that, at some point, creates too many processes, crashing the computer
  • a malicious hacker attack, where the hacker finds a way to run their code on the victim’s system and implements a fork bomb in order to perform a denial of service on that computer

We can prevent a Bash fork bomb from crashing our system by limiting how many processes our user can run.

We can achieve this by editing the /etc/security/limits.conf file with root permissions and setting the maximum number of processes for the user:

user_name hard nproc number_of_processes

Now the question would be, what’s a good number of processes to set as a limit?

A simple way to know a good number is to open as many programs as we’d normally use simultaneously and then count them in the terminal:

$ ps aux -L | cut --delimiter=" " --fields=1 | sort | uniq --count | sort --numeric-sort | tail --lines=1

We should then take that number and multiply it by two to be conservative. We do this because setting a number too low might bring up issues during our day-to-day use.

After that, we can finish editing the /etc/security/limits.conf file and finally reboot the system to apply the new configuration.

4. Helpful Use Cases

As it turns out, fork bombs actually have their uses outside of attackers.

For example, system administrators often use Bash fork bombs in order to test if they have configured a server correctly or to perform stress tests on their systems.

The Bash fork bomb can also be used to test if a watchdog will properly reboot a Linux Embedded Board when the system freezes.

5. Conclusion

In this article, we discussed what a Bash fork bomb is, its implications, and how to prevent it from crashing our systems. We also took a look at how to use the fork bomb for testing purposes.