Details
-
Type:
Language-Specification
-
Status: Active
-
Resolution: Unresolved
-
Labels:None
-
Impact:Unknown 'null' severity
-
Likelihood:Unknown 'null' severity
Description
Noncompliant Code Example
A "check function" (for instance access, stat ... in this case access to verify the existence of a file) is used, followed by a "use function" (open, fopen ...) to write data inside a non existing file. These two consecutive calls create a TOCTOU race condition:
#include <stdio.h> void fopen_with_toctou(const char *file) { if (access(file, F_OK) == -1 && errno == ENOENT) { // the file doesn't exist // it is now created in order to write some data inside FILE *f = fopen(file, "w"); // Noncompliant: a race condition window exist from access() call to fopen() call calls if (NULL == f) { /* Handle error */ } if (fclose(f) == EOF) { /* Handle error */ } } }
Compliant Solution
If the file already exists on the disk, fopen with x mode will fail:
#include <stdio.h> void open_without_toctou(const char *file) { FILE *f = fopen(file, "wx"); // Compliant if (NULL == f) { /* Handle error */ } /* Write to file */ if (fclose(f) == EOF) { /* Handle error */ } }
A more generic solution is to use "file descriptors":
void open_without_toctou(const char *file) { int fd = open(file, O_CREAT | O_EXCL | O_WRONLY); if (-1 != fd) { FILE *f = fdopen(fd, "w"); // Compliant } }