Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: reintroducet stat/fstat comparison, O_NOFOLLOW, and added a description of the inherent TOCTOU

...

Since the behavior of O_NONBLOCK on subsequent calls to read() or write() is unspecified, it is advisable to disable the flag once we are sure the file in question is not a special device.

Code Block
bgColor#ccccff
#ifdef O_NOFOLLOW
  #define OPEN_FLAGS O_NOFOLLOW | O_NONBLOCK
#else
  #define OPEN_FLAGS O_NONBLOCK
#endif

/* ... */

struct stat orig_st;
struct stat open_infost;
int fildes;
int flags;

if (!fgets(filename, sizeof(filename), stdin)) {
  /* handle error */
}

if ((stat(file_name, &orig_st) != 0) || (!S_ISREG(orig_st.st_mode))) {
  /* handle error */
}

/* A TOCTOU exists here, see note */

if ((fildes = open(filename, OOPEN_NONBLOCKFLAGS, O_WRONLY)) == -1) {
  /* handle error */
}

if ((fstat(fildes, &statopen_infost) != 0) {
  /* handle error */
}

if ((orig_st.st_mode != open_st.st_mode) ||
    (!S_ISREG(stat_info.st_mode)))orig_st.st_ino  != open_st.st_ino) ||
    (orig_st.st_dev  != open_st.st_dev)) {
  /* handle errorfile was tampered with */
}

/* Optional: drop the O_NONBLOCK now that we are sure this is a good file */
if ((flags = fcntl(fildes, F_GETFL)) == -1) {
  /* handle error */
}

if ((fcntl(fildes, F_SETFL, flags & ~O_NONBLOCK) != 0) {
  /* handle error */
}

/* operate on file */

Regarding the inevitable TOCTOU vulnerability between the stat() check and open() call, there are essentially four cases that could result from an attacker switching out the file for one of the following:

Type

Note on effect

another regular file

The fstat() verification will fail

FIFO

Either open() will error out and set errno to ENXIO or the open() will succeed and the fstat() verification will fail

link

open() will error out if O_NOFOLLOW is available, otherwise if the link does not point to a special device the fstat() verification will fail

special device

Most systems require superuser privileges to tamper with devices, at which point there is little that can be done

Keep in mind that this TOCTOU is not a problem if the program can guarantee a safe environment for itself by properly managing permissions and ensuring that an attacker cannot have write or modify access to files.

Compliant Solution (Windows)

...