Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Edits

TOCTOU (time-of-check, time-of-use) race condition occurs when a program performs two or more accesses on a filename or path. Typically, the first access is a check to verify some attribute of the file, followed by a call to use the file. An attacker can alter the file between the two accesses, causing the check to succeed but the use to fail. Worse, the use can operate on a different file than the check.

A program that performs a file operation on a filename or path twice creates a race window between the two file operations. This race window comes from the assumption that the filename refers to the same file both times. If an attacker can modify the file, remove it, or replace it with a different file, then this assumption will not hold, and the program will behave badly.

Noncompliant Code Example (POSIX read)

This noncompliant code example tries example attempts to ensure that an open will succeed by first calling the POSIX access() function, which returns zero if the file exists and can be readaccessed using the specified permissions. An attacker can exploit the race window between the access and the open to cause fopen() to fail in spite of the check.Since this

Code Block

...

Code Block
bgColor#ffcccc
langc
#include <stdio.h>
#include <unistd.h> 

intvoid open_some_file(const char *file) {
  FILE *fdf; 
  if (access("./some_file", R_OK | W_OK) !== 0) {
    printf("access granted.\n");
    fdf = fopen("./some_file", "rb+");
    if (NULL == f) {
      /* Handle error */
    }
    /* read file */
    fclose(fdf);
  }

  return 0;
}

Compliant Solution (read)

This compliant solution dispenses with an access call and merely relies on fopen() to verify the file.

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <unistd.h> 

int
void open_some_file(const char *file) {
  FILE *fd; 
  fd f = fopen("./some_file", "rb+");
  if (fdNULL !== NULLf) {
    /* Handle error */
  }
  printf("access granted.\n");
    /* read file */
    fclose(fdf);
  }

  return 0;
}

Noncompliant Code Example (POSIX write)

...

Code Block
bgColor#ffcccc
langc
#include <stdio.h>
#include <unistd.h> 

intvoid open_some_file(const char *file) {
  FILE *fdf; 
  if (access("./some_file", R_OK | W_OK) !== 0) {
    printf("access granted.\n");
    fdf = fopen("./some_file", "wb+");
    if (NULL == f) {
      /* Handle error */
    }
    /* write to file */
    fclose(fdf);
  }

  return 0;
}

Compliant Solution (C11 write)

This compliant solution uses the x mode of fopen(), which was added to added in C11. This mode causes fopen() to fail if the file exists. This check and subsequent open is done without creating a race window. Note that the x mode provides exclusive access to the file if the operating platform provides this support.

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <unistd.h> 

intvoid open_some_file(const char *file) {
  FILE *fdf; 
  fdf = fopen("./some_file", "wb+x");
  if (fdf == NULL) {
    /* Handle error */
  }
  printf("access granted.\n");
    /* write to the file */
    fclose(fdf);
  }

  return 0;
}

Compliant Solution (POSIX write)

...

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

intvoid open_some_file(const char *file) {
  int filefd = open("./some_file", O_CREAT | O_EXCL | O_RDWR);
  if (filefd != -1) {
    FILE *fd; 
    fdf = fdopen(filefd, "rw+");
    if (fdf != NULL) {
      printf("access granted.\n");
      /* write to file */
      fclose(fdf);
    }
    close(filefd);
  }

  return 0;
}

Exceptions

FIO45-EX1: Accessing a path multiple times is permitted if it is requested specifically by the usersa user. A program that accepts commands from a user to read or write a specific filename does not violate this standard. Example programs would include file managers or text editors.

...

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FIO32FIO45-C

High

Probable

High

P6

L2

Bibliography

[Seacord 2013]Chapter 7, "Files"

...