summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAaron Ball <nullspoon@iohq.net>2015-11-12 20:46:02 -0700
committerAaron Ball <nullspoon@iohq.net>2015-11-12 20:48:56 -0700
commit81e50a6059b9c052972aeb2eff09cabf13c8022e (patch)
tree9477162a606c490d191ccdc4c4e57b2a39e72653 /src
parentc9c09ea05be353841818ecd06fdbd09f6a7da5ae (diff)
downloadoper.io-81e50a6059b9c052972aeb2eff09cabf13c8022e.tar.gz
oper.io-81e50a6059b9c052972aeb2eff09cabf13c8022e.tar.xz
Wrote Understanding the Bash Fork Bomb
Updated index for this post
Diffstat (limited to 'src')
-rw-r--r--src/index.ascii2
-rw-r--r--src/understanding_the_bash_fork_bomb.ascii106
2 files changed, 108 insertions, 0 deletions
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:

Generated by cgit