Speak softy, and carry a big fork

Fork is one of the many powerful tools you have at your disposal as a C developer. Take for example the code below. Here was an honest attempt at implementing an example using fork, but things went very wrong.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

// main takes two parameters: argc is the number of command-line
// arguments; argv is an array of strings containing the command
// line arguments
int main (int argc, char *argv[])
{
    int status;
    pid_t pid;
    int i, num_children;

    // the first command-line argument is the name of the executable.
    // if there is a second, it is the number of children to create.
    if (argc == 2) {
        num_children = atoi (argv[1]);
    } else {
        num_children = 1;
    }

    for (i=0; i<num_children; i++) {

        // create a child process
        printf ("Creating child %d.\n", i);
        pid = fork ();

        /* check for an error */
        if (pid == -1) {
            fprintf (stderr, "fork failed: %s\n", strerror(errno));
            perror (argv[0]);
            exit (1);
        }
    }

    /* see if we're the parent or the child */
    if (pid == 0) {
        printf ("Hello from child %d.\n", i);
    }

    /* parent continues */
    printf ("Hello from the parent.\n");

    exit (0);
}

The code is supposed to take in a command line argument of the number of processes to create, but it doesn’t quite behave as expected. What’s wrong it? It may not be obvious from a first pass, but I recommend reading through and figuring out what this code actually does. Run the code with different arguments to get a better idea of what’s happening.

This behavior is the fundamental idea behind an exploit sometimes seen in malicious software called a fork bomb. The code in a fork bomb infinitely spawns new processes, starving the system of resources and effectively crashing it. The simplest fork bomb in C looks like this:

#include <unistd.h>

// WARNING! Run at your own risk!
int main(void)
{
    while(1)
        fork();
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s