Versions Compared

Key

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

...

The following non-compliant code example creates a file with some hard coded filename file_name (presumably in a shared directory such as /tmp or C:\Temp).

Code Block
bgColor#FFCCCC
char filenamefile_name[] = /* hard coded string */;

FILE *fp = fopen(filenamefile_name, "wb+");
if (fp == NULL) {
  /* Handle Error */
}

...

Code Block
bgColor#FFCCCC
char filenamefile_name[L_tmpnam];
FILE* fp;

if (!tmpnam(filenamefile_name)) {
  /* Handle Error */
}

/* A TOCTOU race condition exists here */

fp = fopen(filenamefile_name, "wb+");
if (fp == NULL) {
   /* Handle Error */
}

...

Wiki Markup
This next non-compliant code example attempts to remedy the problem by using the POSIX {{open()}} function, and providing a mechanism to indicate whether an existing file has been opened for writing or a new file has been created \[[Open Group 04|AA. C References#Open Group 04]\]. If the {{O_CREAT}} and {{O_EXCL}} flags are used together, the {{open()}} function fails when the file specified by {{filenamefile_name}} already exists. To prevent an existing file from being opened and truncated, include the flags {{O_CREAT}} and {{O_EXCL}} when calling {{open()}}.

Code Block
bgColor#FFCCCC
char filenamefile_name[L_tmpnam];
int fd;

if (!(tmpnam(filenamefile_name))) {
  /* Handle Error */
}

/* A TOCTOU race condition exists here */

fd = open(filenamefile_name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0600);
if (fd < 0) {
   /* Handle Error */
}

This call to open() fails whenever filename file_name already exists, including when it is a symbolic link. This is secure, but a temporary file is presumably still required. Unfortunately, the method used by tmpnam() to generate file names is not guaranteed to be unpredictable, which leaves room for an attacker to guess the file name ahead of time.

...

Code Block
bgColor#FFCCCC
char filenamefile_name[L_tmpnam_s];
int fd;

if (tmpnam_s(filenamefile_name, L_tmpnam_s) != 0) {
  /* Handle Error */
}

/* A TOCTOU race condition exists here */
fd = open(filenamefile_name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0600);
if (fd < 0) {
  /* Handle Error */
}

...

Code Block
bgColor#FFCCCC
char filenamefile_name[] = "tmp-XXXXXX";
int fd;

if (!mktemp(filenamefile_name)) {
  /* Handle Error */
}

/* A TOCTOU race condition exists here */

fd = open(filenamefile_name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0600);
if (fd < 0) {
  /* Handle Error */
}

...