Versions Compared

Key

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

...

This noncompliant code example opens the file specified by the string file_name for read/write access and then writes user-supplied data to the file.

Code Block
bgColor#FFCCCC
langc
char *file_name = /* something */;
char *userbuf = /* something */;
unsigned int userlen = /* length of userbuf string */;

int fd = open(file_name, O_RDWR);
if (fd == -1) {
   /* handle error */
}
write(fd, userbuf, userlen);

...

Wiki Markup
Some systems provide the O_NOFOLLOW flag to help mitigate this problem. The flag will be required by the forthcoming POSIX.1-2008 standard, and so will become more portable over time \[[Austin Group 2008|AA. Bibliography#Austin Group 08]\]. If the flag is set and the supplied {{file_name}} is a symbolic link, then the open will fail.

Code Block
bgColor#ccccff
langc
char *file_name = /* something */;
char *userbuf = /* something */;
unsigned int userlen = /* length of userbuf string */;

int fd = open(file_name, O_RDWR | O_NOFOLLOW);
if (fd == -1) {
  /* handle error */
}
write(fd, userbuf, userlen);

...

This compliant solution uses the lstat-fopen-fstat idiom illustrated in recommendation FIO05-C. Identify files using multiple file attributes.

Code Block
bgColor#ccccff
langc
char *file_name = /* some value */;

struct stat orig_st;
if (lstat( file_name, &orig_st) != 0) {
  /* handle error */
}

if (!S_ISREG( orig_st.st_mode)) {
  /* file is irregular or symlink */
}

int fd = open(file_name, O_RDWR);
if (fd == -1) {
  /* handle error */
}

struct stat new_st;
if (fstat(fd, &new_st) != 0) {
  /* handle error */
}

if (orig_st.st_dev != new_st.st_dev ||
    orig_st.st_ino != new_st.st_ino) {
  /* file was tampered with during race window */
}

/* ... file is good, operate on fd ... */

...

One way to deal with hard links is simply to disallow opening of any file with two or more hard links. The following code snippet, when inserted into the previous example, will identify if a file has multiple hard links.

Code Block
bgColor#ccccff
langc
if (orig_st.st_nlink > 1) {
  /* file has multiple hard links */
}

...