From 81e50a6059b9c052972aeb2eff09cabf13c8022e Mon Sep 17 00:00:00 2001 From: Aaron Ball Date: Thu, 12 Nov 2015 20:46:02 -0700 Subject: Wrote Understanding the Bash Fork Bomb Updated index for this post --- src/index.ascii | 2 + src/understanding_the_bash_fork_bomb.ascii | 106 +++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 src/understanding_the_bash_fork_bomb.ascii (limited to 'src') diff --git a/src/index.ascii b/src/index.ascii index a301024..9bb810d 100644 --- a/src/index.ascii +++ b/src/index.ascii @@ -8,6 +8,7 @@ Index New Posts ~~~~~~~~~ +* link:?p=understanding_the_bash_fork_bomb[Understanding the Bash Fork Bomb] * link:?p=gentoo:kernel_cleanup[Gentoo:Kernel Cleanup] * link:?p=gentoo:converting_portage_to_git[Gentoo:Converting Portage to Git] @@ -102,6 +103,7 @@ Scripting Git ~~~ +* link:?p=understanding_the_bash_fork_bomb[Understanding the Bash Fork Bomb] * link:?p=Git_as_a_Backup_Solution[Git as a Backup Solution] * link:?p=Git_Basics[Git Basics] * link:?p=Git:Branch_Author_List[Git:Branch Author List] diff --git a/src/understanding_the_bash_fork_bomb.ascii b/src/understanding_the_bash_fork_bomb.ascii new file mode 100644 index 0000000..52d8c47 --- /dev/null +++ b/src/understanding_the_bash_fork_bomb.ascii @@ -0,0 +1,106 @@ +Understanding the Bash Fork Bomb +================================ +:author: Aaron Ball +:email: nullspoon@iohq.net +:revdate: November 12, 2015 + + +== {doctitle} + +I suspect that most Linux users, new and old, have at some point seen the +stereotypical fork bomb, whether they know what it was or not. + + :(){ :|:& };: + +A very cryptic statement that appears to have various forms of smiley faces in +it. But what does it do and how does it work? + + +== What is a fork bomb? + +First, let's start by describing a fork. When a process creates another +process, that's called a process fork. For example, a program needs to read +data from two log files at the same time, so the main program process forks +two children processes, each to read data from the log file into memory. While +those two processes are running, the program consistes of three running +processes: the parent and two children. + +To see this in action, a fun command to run is + + ps -ef --forest + +That command will show you a graphical representation of parent processes and +their children (and their children's children and so on). + + +A fork bomb is is a process that forks off children processes, each of which +forks off its own children processes. For example, assuming each process +creates two, the parent process would create two children processes, each of +which creates two more. The result becomes 1 -> 2 -> 4 -> 16 -> 256 -> 65536. + +The key concept that makes a fork bomb work [so deviously] is that the parent +process of any child processes won't exit until the children exit. In the case +of a fork bomb, the task of a child process is to create more children +processes, thus they never exit because there is no terminus for process +creation. + +To summarize, a fork bomb could fill up a system's process table very fast. In +the example where we created 2 new children for each process, it took 6 steps +before we hit 65536 processes, which would crash many systems. + + +== How does this fork bomb work? + + +To better understand the stereotypical bash forkbomb, let's expand it into more +human-readable code. First, the original forkbomb for easy no-scroll reference. + + :(){ :|:& };: + +Now, let's break the function apart. In bash, there are two ways to define a +function + + function some_name { + # Do stuff here + } + +and... + + some_name() { + } + +The forkbomb mentioned at the beginning of this post uses the second function +syntax. As you can see, using that syntax, it creates a function called *:*. +Now, let's expand this into a much less compressed format now, by using the +first syntax, breaking it into multiple lines, and renaming the function from +*:* to *foo* + + function foo { + foo|foo& + } + foo + + +Now that's much easier to understand. It's fairly clear now that this creates +a function called foo that calls foo, piping the output to another call of foo +that's backgrounded so it can continue (the &), then finishes the function +definition and calls foo to start things off. + +As mentioned, once the function is called, it calls _foo|foo&_, which +basically executes foo, piping the function's output (nothing) to a new +instance of the foo function, and backgrounding that process. However, within +the foo function, it calls foo again, which inside, has two more calls to foo, +etc. Effectively, it recursively creates two children functions that never +close because they each create two children functions that never close because +they each create two children functions... Get the idea? + +Ironically enough, despite how impacting this function can be, it actually does +relatively little work except to create new instances of the function. Kind of +devious that a function that does no real processing can bury a system with +load. + + +[role="datelastedit"] +Last edited: {revdate} + +// vim: set syntax=asciidoc: -- cgit v1.2.3