summaryrefslogtreecommitdiff
path: root/posts/understanding_the_bash_fork_bomb.rst
blob: 56f701533cdcf53e10c98959e24b3b1fb04ee519 (plain)
    1 Understanding the Bash Fork Bomb
    2 ================================
    3 
    4 I suspect that most Linux users, new and old, have at some point seen the
    5 stereotypical fork bomb, whether they knew what it was or not.
    6 
    7 .. code-block:: sh
    8 
    9   :(){ :|:& };:
   10 
   11 A very cryptic statement that appears to have various forms of smiley faces in
   12 it. But what does it do and how does it work?
   13 
   14 
   15 What is a fork bomb?
   16 --------------------
   17 
   18 First, let's start by describing a fork. When a process creates another
   19 process, that's called a process fork. For example, a program needs to read
   20 data from two log files at the same time, so the main program process forks
   21 two children processes, each to read data from the log file into memory. While
   22 those two processes are running, the program consistes of three running
   23 processes: the parent and two children.
   24 
   25 To see this in action, a fun command to run is
   26 
   27 .. code-block:: sh
   28 
   29   ps -ef --forest
   30 
   31 That command will show you a graphical representation of parent processes and
   32 their children (and their children's children and so on).
   33 
   34 A fork bomb is is a process that forks off children processes, each of which
   35 forks off its own children processes. For example, assuming each process
   36 creates two, the parent process would create two children processes, each of
   37 which creates two more. The result becomes 1 -> 2 -> 4 -> 16 -> 256 -> 65536.
   38 
   39 The key concept that makes a fork bomb work [so deviously] is that the parent
   40 process of any child processes won't exit until the children exit. In the case
   41 of a fork bomb, the task of a child process is to create more children
   42 processes, thus they never exit because there is no terminus for process
   43 creation.
   44 
   45 To summarize, a fork bomb could fill up a system's process table very fast. In
   46 the example where we created 2 new children for each process, it took 6 steps
   47 before we hit 65536 processes, which would crash many systems.
   48 
   49 
   50 How does this fork bomb work?
   51 -----------------------------
   52 
   53 To better understand the stereotypical bash forkbomb, let's expand it into more
   54 human-readable code. First, the original forkbomb for easy no-scroll reference.
   55 
   56 .. code-block:: sh
   57 
   58   :(){ :|:& };:
   59 
   60 Now, let's break the function apart. In bash, there are two ways to define a
   61 function
   62 
   63 .. code-block:: sh
   64 
   65   function some_name {
   66     # Do stuff here
   67   }
   68 
   69 and...
   70 
   71 .. code-block:: sh
   72 
   73   some_name() {
   74     # Do stuff here
   75   }
   76 
   77 The forkbomb mentioned at the beginning of this post uses the second function
   78 syntax. With that understanding, as you can see, using that syntax, it creates
   79 a function called ``:``.  Now, let's expand this into a much less compressed
   80 format now by breaking it into multiple lines and renaming the function from
   81 ``:`` to ``foo``
   82  
   83 .. code-block:: sh
   84 
   85     foo() {
   86       foo|foo&
   87     }
   88     foo
   89 
   90 
   91 Now that's much easier to understand. It's fairly clear now that this defines a
   92 function called ``foo`` that calls iteself (recursing), piping the output of
   93 the recursive call to another call of itself, which is then backgrounded so it
   94 can continue (the ``&``). Finally, the function is called to initiate the
   95 cascade.
   96 
   97 As mentioned, once the function is called, it calls ``foo|foo&``, which
   98 basically executes foo, piping the function's output (nothing) to a new
   99 instance of the foo function, and backgrounding that process. However, within
  100 the foo function, it calls foo again, which inside, has two more calls to foo,
  101 etc. Effectively, it recursively creates two children functions that never
  102 close because they each create two children functions that never close because
  103 they each create two children functions... Get the idea?
  104 
  105 Ironically enough, despite how impacting this function can be, it actually does
  106 relatively little work except to create new instances of the function. The end
  107 result however is to fully saturate the process table, leaving no pids
  108 remaining to start new processes, so you can't even execute ``kill`` to stop
  109 it. Kind of devious that a function that does no real processing can bury a
  110 system with load trying to manage all of that nothing.

Generated by cgit