Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

If not properly performed, checking for the existence of symbolic links can lead to time of creation to time of use (TOCTOU) race conditions.

The only function available on POSIX systems to collect information about a symbolic link rather than its target is the lstat() function. This non-compliant code example uses the lstat() function to collect information about the file, checks the st_mode field to determine if the file is a symbolic link, and then opens the file if it is not a symbolic link.

Code Block
bgColor#FFCCCC
char *filename;
struct stat lstat_info;
int fd;
/* ... */
if (lstat(filename, &lstat_info) == -1) {
  /* handle error */
}
if (!S_ISLNK(lstat_info.st_mode)) {
   if ((fd = open(filename, O_EXCL|O_RDWR, 0600)) == -1) {
       /* handle error */
   }
}
write(fd, userbuf, userlen);

Wiki Markup
This code contains a time of creation to time of use (TOCTOU) race condition betwen the call to {{lstat()}} and the subsequent call to {{open()}} because both functions operate on a file name \[[FIO01-A|FIO01-A. Prefer functions that do not rely on file names for identification]\] that can be manipulated asynchronously to the execution of the program.

This compliant solution eliminates the race condition by:

...

Code Block
bgColor#ccccff
char *filename;
struct stat lstat_info, fstat_info;
int fd;
/* ... */
if (lstat(filename, &lstat_info) == -1) {
  /* handle error */ 
}
if ((fd = open(filename, O_EXCL|O_RDWR, 0600)) == -1) {
  /* handle error */
}
if (fstat(fd, &fstat_info) == -1) {
  /* handle error */
}
if (lstat_info.st_mode == fstat_info.st_mode &&
    lstat_info.st_ino == fstat_info.st_ino  &&
    lstat_info.st_dev == fstat_info.st_dev) {
  write(fd, userbuf, userlen);
}

Wiki Markup
Tihs eliminate the TOCTOU condition because {{fstat()}} is applied to file descriptors, not file names, so the file passed to {{fstat()}} must be identical to the file that was opened.  The {{lstat()}} function does not follow symbolic links, but {{fstat()}} does. Comparing modes using the {{st_mode}} field is sufficient to check for a symbolic link.
Comparing i-nodes using the {{st_ino}} fields and devices using the {{st_dev}} fields ensures that the file passed to {{lstat()}} is the same as the file passed to {{fstat()}} \[[FIO05-A|FIO05-A. Identify files using multiple file attributes]\]. 

Time of creation to time of use (TOCTOU) race condition vulnerabilities can be exploited to gain elevated privileges.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FI031 POS35-A C

3 (high)

3 (likely)

2 (medium)

P18

L1

Examples of vulnerabilities resulting from the violation of this rule can be found on the CERT website.

Wiki Markup
\[[Dowd 06|AA. C References#Dowd 06]\] Chapter 9, "UNIX 1: Privileges and Files"
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.19, "Input/output <stdio.h>"
\[[Open Group 04|AA. C References#Open Group 04]\] [lstat()|http://www.opengroup.org/onlinepubs/000095399/functions/lstat.html], [fstat()|http://www.opengroup.org/onlinepubs/009695399/functions/fstat.html], [open()|http://www.opengroup.org/onlinepubs/009695399/functions/open.html]
\[[Seacord 05|AA. C References#Seacord 05]\] Chapter 7, "File I/O"