Versions Compared

Key

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

...

Code Block
bgColor#FFCCCC
struct stat lstat_info;
int fd;
if (lstat("some_file", &lstat_info) == -1) {
  /* handle error */
}
if (!S_ISLNK(lstat_info.st_mode)) {
   if ((fd = open("some_file", O_EXCL|O_RDWR, 0600)) == -1) {
       /* handle error */
   }
}
write(fd, userbuf, userlen);

...

Code Block
bgColor#ccccff
int fd;
if ((fd = open("some_file", O_EXCL|O_RDWR | O_NOFOLLOW, 0600)) == -1) {
  /* handle error */
}
write(fd, userbuf, userlen);

...

Code Block
bgColor#CCCCff
struct stat lstat_info, fstat_info;
int fd;
if (lstat("some_file", &lstat_info) == -1) {
  /* handle error */
}
if ((fd = open("some_file", O_EXCL|O_RDWR, 0600)) == -1) {
  /* handle error */
}
if (fstat(fd, &fstat_info) == -1) {
  /* handle error */
}
if (lstat_info.st_mode == fstat_info.st_mode &&
    lstat_info.st_ino == fstat_info.st_ino  &&
    lstat_info.st_dev == fstat_info.st_dev) {
  write(fd, userbuf, userlen);
}

Wiki Markup
This eliminates the TOCTOU condition because {{fstat()}} is applied to file descriptors, not file names, so the file passed to {{fstat()}} must be identical to the file that was opened.  The {{lstat()}} function does not follow symbolic links, but {{open()}} does. Comparing modes using the {{st_mode}} field is sufficient to check for a symbolic link.
 Comparing i-nodes using the {{st_ino}} fields and devices using the {{st_dev}} fields ensures that the file passed to {{lstat()}} is the same as the file passed to {{fstat()}} (see \[[FIO05-A. Identify files using multiple file attributes]\]).

...