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

Compare with Current View Page History

« Previous Version 11 Next »

Files can often be identified by other attributes in addition to the file name, for example, by comparing file ownership or creation time. For example, you can store information on a file that you have created and closed, and then use this information to validate the identity of the file when you reopen it. Comparing multiple attributes of the file improves the probability that you have correctly identified the appropriate file.

Non-Compliant Code Example

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

FILE *fd = fopen(filename, "r");
if (fd) {
  ...  /* file opened */
}
fclose(fd);

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(filename, O_RDWR);
if ( (fd != -1) && 
     (fstat(fd, &st) != -1) &&
     (st.st_ino == ino) &&
     (st.st_dev == dev) 
   ) {
   ...	  
}
close(fd);

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 identifies the file. The st_dev value is not necessarily consistent across reboots or system crashes, however.

It is also 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 which is opened. See [[FIO01-A]] for more information.

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

struct stat st;
dev_t dev = 773; /* device */
ino_t ino = 11321585;  /* file serial number */
FILE *fd = fopen(filename, "r");
if ( (fd) && 
     (fstat(fileno(fd), &st) != -1) &&
     (st.st_ino == ino) &&
     (st.st_dev == dev) 
     ) {
   ...
}
fclose(fd);

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.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FIO05-A

2 (medium)

2 (probable)

2 (medium)

P8

L2

Examples of vulnerabilities resulting from the violation of this recommendation can be found on the CERTwebsite.

References

[[Seacord 05]] Chapter 7, File I/O
[[ISO/IEC 9899-1999]] Sections 7.19.3, Files; 7.19.4, Operations on Files
[[Open Group 04]] The open function, The fstat function
[[Drepper 06]] Section 2.2.1 Identification When Opening

  • No labels