TOCTTOU

Overview

There is a special type of race condition in software; it occurs when checking for a condition before using a resource. Sometimes, the condition can change between the time of check and the time of use. The security vulnerability resulting from this is called time-of-check to time-of-use (TOCTTOU) race condition vulnerability.

Example

Consider the root-owned Set-UID program below:

if (!access("/tmp/X", W_OK))
{
    /* the real user has the write permission. */
    f = open("/tmp/X", O_WRITE);
    write_to_file(f);
}
else
{
    /* the real user does not have the write permission. */
    fprintf(stderr, "Permission denied\n");
}

The access() syscall check rUID and the open() syscall only checks eUID. Since a root-owned Set-UID program runs with an eUID 0, the check performed by open() will always succeed. That is why the code puts an additional check using access() before open().

In this case:

  • TOC => if (!access("/tmp/X", W_OK))

  • TOU => f = open("/tmp/X", O_WRITE)

There is a window between the time when the file is checked (TOC) and the time when the file is opened (TOU). If we make a symlink /tmp/X => /etc/passwd in this window, /etc/passwd will be opened with eUID 0 therefore we can write to it. At this stage, we can add an entry to /etc/passwd and su that new user.

Reference

Last updated