next up previous
Next: Unix sockets and named Up: Working with Temporary Files Previous: Creating a One-shot File

Exchanging data via a temporary file

This leads us straight to a related topic. Consider an application that uses a file to exchange data between several instances of itself. For instance, programs using the Kerberos authentication system usually store credentials (known as tickets in the Kerberos world) in /tmp/krb5cc_XXX where XXX is the user ID. When the file doesn't exist, it should be created; if it exists, tickets should be appended to it.

It is tricky to do this safely, because simply using O_EXCL doesn't apply here - O_EXCL tells the kernel to fail if the file is there already. But in this case, we don't want to fail; we want to append to the file!

Sometimes people recommend a solution that goes like this:

    fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, 0644);
    if (fd < 0) {
        /* File exists, just open it */
        if (errno != EEXIST)
            fatal("%s: %m", filename);
        if (lstat(filename, &stb1) < 0)
            fatal("%s: %m", filename);
        fd = open(filename, O_WRONLY);
        if (fd < 0 || fstat(fd, &stb2) < 0)
            fatal("%s: %m", filename);
        if (S_ISLNK(stb1.st_mode)
         || stb1.st_ctime != stb2.st_ctime
         || stb1.st_dev != stb2.st_dev
         || stb1.st_ino != stb2.st_ino)
            fatal("symlink attack");
    }
    fp = fdopen(fd, "w");

The idea behind this is that when you follow a symlink, it is extremely unlikely the file you end up opening has the same creation time, device and inode number as the object you started with.

This approach has several problems:

Assume an attacker creates a credential cache file for your uid. If he sets the file's mode bits to 600, you will not be allowed to read or write this file, and will therefore be unable to store your Kerberos ticket! Without Kerberos ticket, you will be unable to access network services securely (if at all), etc.

On the other hand, if the attacker sets the file's mode bits to 644, and if Kerberos were stupid enough not to check this,4.3 you would be able to store your tickets in this file, but the attacker would be able to read them! And if the attacker is able to get your tickets, he can impersonate you for as long as the ticket is valid (several hours, usually).

The next problem is that the code snippet above doesn't protect you from attacks using hard links. And finally, while the attack does detect symlinks attacks, it doesn't do so until after you've opened the file. Which is okay for regular files, but for various device files, simply opening them already has side effects. For instance, some tape devices rewind the tape automatically when you open them.


next up previous
Next: Unix sockets and named Up: Working with Temporary Files Previous: Creating a One-shot File
Olaf Kirch 2002-01-16