Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: EXP37 compliance

...

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_st;
int fd;
int flags;
char *file_name;

/* initialize file_name */

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

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

/* A TOCTOU race condition exists here, see below */

fd = open(file_name, OPEN_FLAGS | O_WRONLY, S_IRWXU);
if (fd == -1) {
  /* handle error */
}

if (fstat(fd, &open_st) != 0) {
  /* handle error */
}

if ((orig_st.st_mode != open_st.st_mode) ||
    (orig_st.st_ino  != open_st.st_ino) ||
    (orig_st.st_dev  != open_st.st_dev)) {
  /* file was tampered with */
}

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

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

/* operate on file */

close(fd);

...