114 comments

[ 1.6 ms ] story [ 257 ms ] thread
This was a right of passage for CS students when I was in school - to (usually) accidentally write one when trying to implement some server or service. Fortunately most "modern" UNIX systems at our school by then (mid 1990s) had per user process limits so you'd just screw yourself up.
In my school it was my "Since there are limits and no one can tell me what they are, I can figure them out by counting the number of forks that I did until it blocks" that made our head sysadmin try figuring out how to add the limits
Hm. The way I got introduced to fork bombs was someone asking me in their most innocent voice: "what kind of output do you think this will generate?".
The real issue is even with the limits, when the entire operating systems class was learning about forking it was really easy for a distributed fork bomb to occur.
initd also had a habit of killing child processes once the parent dies so even if you lock yourself up you could in theory log out and just wait a while (unless you nohup the process, then you are fucked)

No such luck for the first guy I knew who fork-bombed himself on a Sequent.

You could really be a jerk and do this...

    while true

        try:
            os.fork()

        except Exception as e:
            continue
Change that `except Exception:` to just a bare `except:` to catch KeyboardInterrupts as well and prevent Ctrl+C from killing any of them while it expands.
or "except BaseException"
(comment deleted)
But what's your point? You can also be a jerk and do

    $ cat nice.sh
    rm -rf $HOME
    $
In the end the user trusts the program/script to not be harmful. That's why we have the browser platform (which shields programs (aka web apps) from the local file system) and advanced permission management in the popular app stores ("this app wants to access your local file system").
> That's why we have the browser platform (which shields programs (aka web apps) from the local file system) and advanced permission management in the popular app stores ("this app wants to access your local file system").

Don't tell browsers that. Javascript hooks for everything, from your clipboard (hope you don't use a password manager), to Bluetooth (oh you like screaming in your music?), and even your USB devices (is your $HOME mounted over USB?)...

A Python fork bomb was my first major achievement in college. Four lines of code took out a server. I'd like to claim it was a great achievement in hacking but nope, just trying to grok concurrency and failing hard.
I did this exact thing with Perl, 1993...I'd just switched majors from English to CS. Very much expected an invitation to switch back.
Did not find go in the examples, so here is how you do it:

for {

  go main()

}
Huh. Does that actually create multiple processes? My impression was that go doesn't fork(2).
Correct, it only spawns goroutines. It will still eat as much CPU as possible, but will be much easier to get "a word in edgewise" since it's only one process. Part of why fork bombs are nasty is that the OS scheduler can't tell the processes shouldn't be scheduled as easily as it will tell that a single CPU-bound process should be scheduled out forcibly when its timeslice is up (or whatever exact thing the scheduler is doing).

Also, when the OOM-killer gets around to killing your Go program, it'll take the whole thing down in the single OS process, rather than a fork bomb where you have to get all the processes.

Writing a true Go forkbomb is actually a bit harder, because as with many such runtimes designed from top-to-bottom around the idea of having a lot of threads, "fork" is not readily available. It's generally not meaningful to fork a highly multi-threaded program. The closest you could get would be to repeatedly execute /proc/self/exe over and over, which will come close, but probably still somewhat slower.

This is one instance where I prefer perl:

   fork while fork
I don't believe this is correct. It will just spawn green threads, which are neither system threads nor processes. You'd really want to use syscall.ForkExec: https://golang.org/pkg/syscall/#ForkExec

EDIT: thinking about this further, I don't think that would be right either, as state from the process won't come over with the fork. So maybe there isn't a way?

I like fork bombs that actually limit or halt the system. Creating a sub-process of some kind in language X usually boils down to multiple processes getting killed/stalled or - if there is one - a VM to crash. Meh.

Example: JavaScript vs "%0|%0"

I used to build .bat(ch) scripts that would do this to crash the computers in middle/jr/high school to get out of schoolwork.

With limited computers in the computer lab this was especially efficient if you set them to open, spawn, and replicate on startup. The old systems could barely handle it and would just error out and the cycle continued.

In high school we had access to the Univac 90/70 at the local college. It supported interactive use via dial up terminals and batch jobs. There were exactly two slots in the batch queue. I wrote an assembler program which created a last-chance exit handler and then went to sleep. In the exit handler, it spawned two new copies of itself in the batch queue. Eventually the operator (who wore a NORML pin on his blue jean jacket) noticed a job was stuck in one of the active slots. So he killed it.

Later, he came out of the machine room and asked me to look at something. There were a whole bunch of stalled batch jobs and two jobs sleeping in the active slots. I calmed him down and showed him the equivalent of "kill -9" and promised never to do it again.

I wanted to try this out, but I didn't want to kill my daily driver. I fired up a Raspberry Pi 3. perl -e 'fork() while 1;' took it down in about two seconds. I couldn't even switch to a different TTY to kill the processes.
> I couldn't even switch to a different TTY to kill the processes

An interesting technique i've heard is to do: ``` while true; do sleep 10m &; done ``` The goal is to exhaust the PID space, which will cause forking to fail and eventually bring the system back under control.

I have bash fork bomb engraved on my AirPods pro; it is a great conversation starter.
I don't get it, is there some joke here?
You can choose to get your AirPods engraved when you order them. It doesn't cost anything extra so you might as well engrave something funny.
I accidentally wrote a fork bomb in a shell script last week. It went like this:

    foo() {
       echo "$1" | foo
    }
Then called foo later. The 2nd occurrence of foo was a typo for something with a very similar name. Took me a few reboots before I realized this.

I find this a bit more interesting than the cited shell example because it does not involve the & token. Just pipes.

I related a story recently about a casual friend who decided to mess with me by using email spam. Instead of learning to do loops in csh, he wrote a recursive variant a lot like what you have here. He had to go to the admin to get back into his account.

My favorite bit was he showed me the code, I saw the problem and rather than telling him how to flood my mailbox properly (because really, who would?) I just said, "You don't want to do that..." and walked away.

Story time: I once worked part time with a company, and their DBA was doing a project to look up all the IP addresses that had been logged into one of their database tables. For every address he was running a bash script to do the reverse lookup.

This was going to take a few days to run, largely because it was forking 10-20 times for every IP address, most of the lookups themselves were fairly quick (though some weren't). I explained to him that forks are fairly expensive operations, and every line in his shell script was 1+ forks.

I thought this would be an easy win, I picked up a multi-threaded DNS lookup tool and showed him that it could look up a thousand addresses in < a second. "Oh, so I can just replace the "nslookup" with this other program in my script?"

I explained that he would need to make a file with all the IP addresses he needed to look up, I'd run the program on a server at our data center (to not clog the office T1), and then I'd give him back a file containing "address,name".

"Oh... So I'd have to correlate each address to a name myself? I can't do that, I need to run this script." In my head I said "You're the DBA, how can you NOT correlate this data?"

Ooh, this is fun.

I worked in a hospital years ago as an IT Tech. I realized one day the printers were not on a separate VLAN. The network guy didn’t seem to care so I wrote a short telnet script to submit a 1000 page (blank) print job to his office printer, flash all the lights and change the display to PC LOAD LETTER. I hit enter and 5 min later sure enough there was a ticket in my queue to diagnose the printer. I killed the script, set the lights to normal and went to his office. Never was able to replicate his complaint...

Replacing his automated process with 2-3 manual steps and with a dependency on you. Yeah, he probably said whatever popped into his mind to make you go away.
I did this inadvertently in the 80s on an Encore Multimax, a parallel computer base don NS 32k processors. I was writing a parallel program in assembly that had to call fork() in a loop to spawn a few child processes. I did not realize that register contents are not copied over to the child process after a fork call and the loop counter was in a register. They had to actually power down the system to get it out of this state :-)
Why was the child process still in the loop forking though?
When you do a fork in a loop, the child process wakes up in the same loop.
Yes, but the way you write child processes is to check the return of fork() and then break out of whatever the parent was doing and go into a child function.
Slightly unrelated, but what amazes me is the fact that every living organism, in a nutshell, is a fork bomb.
With s/ulimit/Hayflick limit/
"what amazes me is the fact that every living organism, in a nutshell, is a fork bomb."

Luckily the lazy sysadmin takes a lifetime to notice and correct the issue:)

Cancer is a fork bomb, most cells are luckily a bit nicer than that :)
Most of them are. But eg worker bees ain't.
Working at a big bank in the early 90's we all had Sparks on our desks. If you walked away without your screen locked, you might come back to find 'ls' aliased to a fork bomb or 'rm -rf *' or something else fun. The guy who sat next to me was truly a master. He would start with aliasing cat, more, ls, cd and then alias itself.

The other fun trick was finding someone who had left xhost+ open and while a boss was at their desk, popping open NSFW pictures on their screen in an xv window.

> The other fun trick was finding someone who had left xhost+ open and while a boss was at their desk, popping open NSFW pictures on their screen in an xv window.

Did this ever end up actually getting someone in trouble? I've worked at a few places where it certainly would.

No. There was some judgement involved. (Also back in those days, there were honestly a lot fewer NSFW images floating around -- this is pre Netscape days.) The goal was to freak people out, not get them (or you) fired.
> back in those days, there were honestly a lot fewer NSFW images floating around

How far back would this be? The people I know who lived through the '90s don't seem to agree…

I stopped a few people from doing this much mischief on a couple occasions and substituted minor mischief instead.

A friend and I arrived at changing their .plan or .project to say "I really need to learn to log out when I leave the computer lab." then log them out and amuse ourselves with how long it would take them or their friends to notice.

What I should have done was note the account name and check in from time to time to see how long it took, but I apparently wasn't that forward-looking.

(comment deleted)
Adding "echo sleep 1 >> ~/.profile" to .profile should be adequate
Oops. I said .profile but meant .project

However I do believe I knew another person who put a sleep and a giant banner in .profile to drive the point home.

  echo "ponysay remember to log out" >> .profile
or maybe:

  echo "ponythink i should always log out" >> .profile
(or the lesser cowsay)
The early Suns had no security on /dev/framebuffer so one could remote into someone else's machine, and run a process that would continuously dump their screen to yours. The LAN was fast enough to get a near-realtime display that would update every few seconds. Obviously one could do the opposite and send NSFW content to the remote screen as well. No need for any XWindows permissions because the hardware layer access was wide open.

They had a similar security issue with /dev/audio where one could "bug" a remote machine and play the audio locally.

Or just cat core dumps to /dev/audio. Actually, don't do that. Most of the time you'd get a panic. :/
We did both of those. We took screen caps of our managers -- the issue with that was that there was a noticeable pause when you were snapping and we were afraid of getting caught.

In terms of audio there was a desk analyst on the MBS trading desk who wrote a script that would play a clip of someone in a thick accent screaming 'You are a stupid man!' on the targeted machine. The traders and analysts did it to each other for a while. When that got boring and they modified the script to play it on all the machines on the MBS trdaing desk, repeatedly. When the head of mortgage research would stop by to speak to one of the traders, someone would quite subtly run the script and every ones machine would start barking 'You are a stupid man!'

Weirdly it never occurred to us to use the microphone.

For Christ's sake. This comment made me laugh so hard because you just gave me some ideas for a colleague that keeps leaving his screen unlocked. :)
please don't alias ls to rm -rf ....

it is not funny.

Rule of thumb: funny things don't cause (permanent) damage. Therefore aliasing something to `rm -rf` is definitely _not_ funny.
Well, your coworker surely would have proper backups of all the important stuff, wouldn't he?

Snark aside, I agree. Accumulating 'sleep 1' in their login-scripts is more fun anyway.

Naa that's too nasty. However, a sleep or something that gets printed just for fun is less harmful and somewhat fun :)

I got downvoted. I think my colleague also reads HN. :p

I worked in IT at a hospital where leaving workstations unlocked is a big no-no. Any time my coworkers did so it was standard procedure to do the following:

1) Change all their desktop icons to target shutdown.exe (I had a script on the shared drive for this).

2) Screenshot the desktop, rotate it 180 in paint then set it to the desktop background.

3) Select all the icons on their destop and hide them.

4) Close all the open applications.

5) Hide the task bar.

6) Hit CTRL+ALT+Up Arrow to enter “projector mode” and get the inverted desktop screenshot back to “normal” but completely screwing up mouse movement.

7) Turn the monitor off.

8) Unplug the keyboard and mouse.

Always fun to watch them struggle through the process in reverse just to end up shutting down when trying to open outlook.

I had an internship at a mostly Apple place at one point. Using the mac `say` command with cron or a timeout in the background was a lot of fun.

One of the Linux guys had a script that detected changes to his wallpaper, set it back to the previous one and insulted the person who attempted to change it.

I had a great cron prank that I pulled on the only other linux user at my high school 2 years ago. It made a folder, took a screenshot of his background, moved all of his desktop into said folder, then changed the background to the screenshot. In retrospect, It was probably overkill, but at least he learned to use ctrl+alt+l when sharing a lunch period with another linux enthusiast.
Iirc, Champaign-Urbana had a C fork bomb source code spray painted on an underpass wall. I suppose it relied on a passing victim to enter it into their own computer ;)
I love that they fork-bombed a bridge!
Late 1970s. Two interns are reading system call manuals; we're on a v6 Unix system, running on a PDP-11/45.

Like many bad ideas, it starts with an innocent question: "What happens if we recursively fork?"

Five minutes and a couple of C compiles later, we're sitting at the DEC printing console watching the system panic. The sysadmin comes running in a minute later.

"What did you THINK would happen?"

We explained that we didn't know, and we wanted to find out. He rebooted the system, fixed up a couple of busted inodes with ncheck and clri and so forth (this, children, was in the days before fsck...) and went back to his meeting, grumbling "... (inaudible) interns..."

And that's when I got seriously interested in how kernels worked.

Not exactly the same, but my dad told me the story that when he was in computer-lab in college, it was the first class in his school to have brand new Apple II computers. They drummed into the students' heads "these are not all connected to the central mainframe; if you ever break something, just reboot the computer and everything will be cleared and it'll be fine".

Well, I guess my dad took that as a challenge, and doing something using some weird recursive assembly and trying to reclaim some extra RAM by using the ROM chip (not 100% sure what he was trying to do), he managed to completely brick the machine, permanently breaking it.

Apparently they were pretty pissed at him, but he rebutted with "Well, you guys told me that I couldn't break it just by coding!" I guess they begrudgingly agreed and never tried to make him pay for it or anything like that, but they did announce to the class the next day that apparently you can break the machines, and to not do anything too clever without a professor looking at it.

I have the shell one as a t-shirt and it is fun to see who "gets it" when I wear it to work.
why does shell/bash needs to call the bomb twice?
It just makes it go faster. If every call to foo() spawns two threads, it spawns exponentially more threads than if each call spawns one thread.
We were rewriting a program from multithreaded to multiprocess execution. But instead of launching a slave, the master launched another master.
In the very early days of the Internet I was running a small ISP and I ran a fancier version of this:

    for word in `cat /usr/share/dict`; do whois "$word.com"; done
and shortly got a phone call from Network Solutions, "What the hell are you guys doing? You're hammering us?"
This remember me a program I wrote in high school in Pascal.

I think it was like this: Program Bomb uses crt,graph; Var Graphics,Mode: smallint; begin Graphics:=Detect; Mode:=detectMode; while(1!=0) InitGraph(Graphics, Mode,'');

It killed an old PC with Windows 2000

When I was taking an operating systems class I wrote a fork bomb to play with:

    ~ $ gcc fork-bomb.c
    ~ $ ./a.out
I saw that it did indeed crash my lab machine, and when it rebooted I went on with my life.

Our CS lab had a central server which served a lot of important functions and also was the terminal server you could SSH into when working from your dorm. All of these had shared home directories.

Late one night working from my dorm before a big project was due I ran:

    project $ gcc project.c
    project $ ~/a.out  # note the '~'
And forkbombed the central server. A lot of people were pretty mad at me.

Lessons learned:

* People should not be logging into the central server to do their work, or it should at least have nproc limits

* Always name your executables (gcc foo.c -o foo)

* Don't leave bombs lying around

> Don't leave bombs lying around

I'd say that's probably good advice regardless of your profession ;)

...or it should at least have nproc limits

I believe that nproc limits are only useful against accidents. In particular the following shell script is very good at taking out systems no matter what limits you set.

   #!/bin/sh
   perl -e '1 while push @big, 1` &
   $0 &
   $0
If you prevent it from taking out all of the process spots, it still is going to wipe out your memory. If you set paranoid enough limits on both memory and process spots, the system is going to be unusable for normal use cases.
Couldn't you reserve, say, 2% of memory and process ids for root?
There is no API for that currently. And there is pressure to not add new complications around memory management because allocating memory is so often called that it affects the performance of everything.
I accidentally took down Netcom with a fork bomb in the early 90's. They quickly discovered the problem and had the system back up within about 10 minutes, after which I found that I could no longer log in because they had banned my account.

I called them up and explained that it was an accident, but also asked why they did not enforce quotas on user accounts to prevent such things. They thanked me and re-enabled my account right away.

I think everybody discovers, and then has fun with, this in their first Systems course on the shared school servers. In mine I discovered something much more fun: https://linux.die.net/man/1/talk

I found some ascii art of the trollface (https://i.kym-cdn.com/entries/icons/original/000/000/091/Tro...) and saved it to a file, then wrote a script that would find user $1 and infinitely "talk" trollfaces at them, making their terminal completely unusable. Then I'd run it against my friends when we were working in the computer lab :)

Shared Unix systems are rife with prank opportunities

net send in high school was pretty hilarious. leave to go get a book in the library and someone is gonna net send from your terminal something dumb to the whole school. took them forever to turn it off
> Shared Unix systems are rife with prank opportunities

My favorite was `cat /dev/dsp > ssh otherbox 'cat > /dev/dsp'`

I could talk into my laptop's microphone and it would play over the speakers on my classmate's workstation.