You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 25 Next »

Files can often be identified by other attributes in addition to the file name, for example, by comparing file ownership or creation time. Information about a file that has been created and closed can be stored and then used to validate the identity of the file when it is reopened.

Comparing multiple attributes of the file increases the likelihood that the reopened file is the same file that had been previously operated on.

Non-Compliant Code Example

This non-compliant code example relies exclusively on the file name to identify the file object.

FILE *fd = fopen(file_name, "w");
if (fd) {
  /* write to file */
  fclose(fd);
}
else {
  /* handle error condition */
}

/* reopen file_name */
fd = fopen(file_name, "r");
if (fd) {
  /* read from file */
  fclose(fd);
}
else {
  /* handle error condition */
}

There is no guarantee that the file opened for reading is the same file that was opened for writing.

Compliant Solution (POSIX)

In this compliant solution, the file is opened using the open() function. If the file is successfully opened, the fstat() function is used to read information about the file into the stat structure. This information is compared with existing information about the file (stored in the dev and ino variables) to improve identification.

struct stat st;
dev_t dev; /* device */
ino_t ino; /* file serial number */

int fd = open(file_name, O_WRONLY);
if ((fd != -1) && (fstat(fd, &st) != -1)) {
  ino = st.st_ino;
  dev = st.st_dev;
  /* write to file */
  close(fd);
}
else {
  /* handle error condition */
}

/* reopen previously written file */
fd = open(file_name, O_RDONLY);
if ((fd != -1) &&
    (fstat(fd, &st) != -1) &&
    (st.st_ino == ino) &&
    (st.st_dev == dev)
   ) {
  /* read from file */
  close(fd);
}
else {
  /* handle error condition */
}

Alternatively, the same solution could be implemented using the C99 fopen() function to open the file and the POSIX fileno() function to convert the FILE object pointer to a file descriptor.

The structure members st_mode, st_ino, st_dev, st_uid, st_gid, st_atime, st_ctime, and st_mtime should all have meaningful values for all file types on POSIX-compliant systems. The st_ino field contains the file serial number. The st_dev field identifies the device containing the file. The st_ino and st_dev, taken together, uniquely identify the file. The st_dev value is not necessarily consistent across reboots or system crashes, however, so you may not be able to use this field for file identification if there is a possibility of a system crash or reboot before you attempt to reopen a file.

It is necessary to call the fstat() function on an already opened file, rather than calling stat() on a file name followed by open() to ensure the file for which the information is being collected is the same file that is opened. See [[FIO01-A. Be careful using functions that use file names for identification]] for more information on avoiding race conditions resulting from the use of file names for identification.

Risk Assessment

Many file-related vulnerabilities are exploited to cause a program to access an unintended file. Proper identification of a file is necessary to prevent exploitation.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

FIO05-A

2 (medium)

2 (probable)

2 (medium)

P8

L2

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

[[Drepper 06]] Section 2.2.1 "Identification When Opening"
[[ISO/IEC 9899-1999]] Section 7.19.3, "Files," and Section 7.19.4, "Operations on Files"
[[MITRE 07]] CWE ID 37, "Path Issue - Slash Absolute Path"; CWE ID 38, "Path Issue - Backslash Absolute Path"; CWE ID 39, "Path Issue - Drive Letter or Windows Volume"; CWE ID 62, "UNIX Hard Link"; CWE ID 64, "Windows Shortcut Following (.LNK)"; CWE ID 65, "Windows Hard Link"
[[Open Group 04]] "The open function," "The fstat function"
[[Seacord 05]] Chapter 7, "File I/O"


FIO04-A. Detect and handle input and output errors      09. Input Output (FIO)       FIO06-A. Create files with appropriate access permissions

  • No labels