next up previous
Next: Symlink Flipping Up: Working with Temporary Files Previous: Falling into the link

Defenses that Don't Work

Programmers faced with this sort of problem for the first time often end up implementing an approach that looks more or less like this:

    snprintf(filename, "/tmp/mbox.%s", getlogin());
    ...
    if (lstat(filename, &stb) >= 0 || S_ISLNK(stb.st_mode))
        fatal("*** symlink attack ***");
    fp = fopen(filename, "w");

While this stops the simple form of the attack, it doesn't really protect you.

The first problem is that it doesn't help against hard links. An attacker can create a hard link named mbox.joe to any file on the same file system as /tmp. On many systems, where /tmp resides in the root file system, this includes files in /etc, so the root user would be a promising target.

The second problem is that the lstat call and subsequent file operation are not atomic, i.e. a certain amount of time passes between the lstat check and the fopen call during which a context switch may occur, and another process started by the attacker would be allowed to run. During that time window, the attacker could create the symlink.

This is called a race condition.

This sounds like a very hypothetical sort of attack, because the time window is just a couple of milliseconds. To illustrate why this is a very real threat, I'll describe some common attacks against this type of code.


next up previous
Next: Symlink Flipping Up: Working with Temporary Files Previous: Falling into the link
Olaf Kirch 2002-01-16