11
#include <unistd.h>
int main(int argc, char* argv[]) {
  while(1)
  {
    fork();
  } 
}

I run this program on my linux, nothing outputs on the terminal, the OS seems go dead. Does linux have any protection measure to such program which can run out of memory?

2
  • 2
    I suspect the impact would be a lot less if you didn't follow the bad advice many distros give to create a large swap partition... Jun 10, 2012 at 16:59
  • 1
    Does "not creating any new processes after hitting 65k" count as counter-measure? ;)
    – Bobby
    Jun 12, 2012 at 11:02

5 Answers 5

19

This is known as a fork bomb.

Does linux have any protection measure to such program which can run out of memory?

Not really. Each fork produces a new process, with its own virtual address space and memory usage. So each copy is relatively small. Eventually, you'll use up all the physical+swap memory on the system, and the out-of-memory (OOM) killer will start killing individual processes. But the fork bomb will still be creating processes just as fast (if not faster).

One way to prevent this occurring in the first place is to limit the number of user processes, using ulimit -u (assuming you're using Bash; other shells will have equivalents).

4
  • 2
    One thing to note is that ulimit is specific to bash; other shells will likely have the same built-in command, but maybe with a different name.
    – Jay
    Jun 10, 2012 at 15:37
  • @Jay: Fair point. I've noted that in the answer now, thanks! Jun 10, 2012 at 15:38
  • 2
    limiting memory/file descriptors per user should be enough. Limiting memory per user is always a good idea. When a process is killed (oom), the watchdog should send a notification so the BOFH could boot 'the rogue' user w/ all belonging processes off the system
    – bestsss
    Jun 10, 2012 at 15:40
  • I believe you can also set some limits through login parameters
    – p_l
    Jun 11, 2012 at 7:32
11

Yes, although it may not be enabled by default on your system. The setrlimit system call defines system limits -- including the number of processes per user.

Let's look at it first in the kernel API (since you mentioned "linux"): you can use the manpage for setrlimit, which will tell you to do something like

#include <sys/resource.h>
...

struct rlimit  r;

rnew.r_cur = 40;
rnew.r_max = 50;
setrlimit(RLIMIT_NPROC,&r);

This will set the maximum processes per user (RLIMIT_NPROC) to 40 (soft limit) and 50 (hard limit).

Now, from the shell, if you use bash, you can use the ulimit built-in command:

ulimit -u
29089

You can set the limit by passing it as an argument:

ulimit -u 100

ulimit --help will show you that there are several other limits you can set (one which may be of interest is the maximum number of file descriptors used by the user).

7

It depends if you want to use it on user level or system level. On user level the ulimit(or corresponding commands for other shells) would be easiest solution.

However on system level there are mechanisms to prevent malicious users (or just not using ulimit) from stopping the system. Linux cgroups mechanism can limit the resources on per-group basis. You can force (by pam_systemd machanism) the user session to be in specific group. This have other benefits for, for example, CPU scheduler.

2
  • 1
    +1: cgroups are really new, and most people don't know much about them yet. Where can we learn more?
    – Ken Bloom
    Jun 10, 2012 at 19:04
  • 1
    @KenBloom: 1. by browsing /sys/fs/cgroup/ 2. by searching in google 3. by browsing through make menuconfig 4. By looking into /usr/src/linux/Documentation/cgroups 5. By reading systemd documentation. Sorry I cannot help more but I used only those resources. I used cgroups on desktop to control resources. Jun 10, 2012 at 19:19
6

Use ulimit -u from the bash shell to set a limit on "max user processes".

From the C shell, you use the limit command.

If you need a system call to do this, use the setrlimit call to set RLIMIT_NPROC.

1

Since the most recent answers here are over 3 years old, I want to point out that newer Kernels (since 4.3) have explicit support to prevent fork bombs via the new "PIDs subsystem". (See https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=49b786ea146f69c371df18e81ce0a2d5839f865c and https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=917d8e2d10f40e28aa9e0d824b2e5b8197d79fc2)

You must log in to answer this question.