 
                            ...
| Code Block | ||||
|---|---|---|---|---|
| 
 | ||||
| char *file_name;
/* Initialize file_name */
FILE *fd = fopen(file_name, "w");
if (fd == NULL) {
  /* Handle error */
}
/*... writeWrite to file ...*/
fclose(fd);
fd = NULL;
/*
 * A race condition here allows for an attacker to switch 
 * to switch out the file for another. 
 */
/* ... */
fd = fopen(file_name, "r");
if (fd == NULL) {
  /* Handle error */
}
/*... readRead from file ...*/
fclose(fd);
fd = NULL;
 | 
...
| Code Block | ||||
|---|---|---|---|---|
| 
 | ||||
| struct stat orig_st;
struct stat new_st;
char *file_name;
/* Initialize file_name */
int fd = open(file_name, O_WRONLY);
if (fd == -1) {
  /* Handle error */
}
/*... writeWrite to file ...*/
if (fstat(fd, &orig_st) == -1) {
  /* Handle error */
}
close(fd);
fd = -1;
/* ... */
fd = open(file_name, O_RDONLY);
if (fd == -1) {
  /* Handle error */
}
if (fstat(fd, &new_st) == -1) {
  /* Handle error */
}
if ((orig_st.st_dev != new_st.st_dev) ||
    (orig_st.st_ino != new_st.st_ino)) {
  /* fileFile was tampered with! */
}
/*... readRead from file ...*/
close(fd);
fd = -1;
 | 
...
Call the fstat() function on a file that is already opened instead of calling stat() on a file name followed by open(). This Doing so ensures that the file for which the information is being collected is the same file that is already opened. See FIO01-C. 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.
...
| Code Block | ||||
|---|---|---|---|---|
| 
 | ||||
| char *file_name;
FILE *fd;
/* Initialize file_name */
fd = fopen(file_name, "w+");
if (fd == NULL) {
  /* Handle error */
}
/*... writeWrite to file ...*/
/* goGo to beginning of file */
fseek(fd, 0, SEEK_SET);
/*... readRead from file ...*/
fclose(fd);
fd = NULL;
 | 
...
In this noncompliant code example, the programmer's intent is to open a file for reading, but only if the user running the process owns the specified file. This requirement is a more restrictive requirement than that imposed by the operating system, which requires only that the effective user have permissions to read the file. The code, however, relies solely on the file name to identify the file.
...
| Code Block | ||||
|---|---|---|---|---|
| 
 | ||||
| struct stat st;
char *file_name;
/* Initialize file_name */
int fd = open(file_name, O_RDONLY);
if (fd == -1) {
  /* Handle error */
}
if ((fstat(fd, &st) == -1) ||
   (st.st_uid != getuid()) ||
   (st.st_gid != getgid())) {
  /* File does not belong to user */
}
/*... readRead from file ...*/
close(fd);
fd = -1;
 | 
...
Risk Assessment
Many file-related vulnerabilities are exploited to cause a program to access an unintended file. Proper file identification is necessary to prevent exploitation.
| Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level | 
|---|---|---|---|---|---|
| FIO05-C | medium | probable | medium | P8 | L2 | 
...
| Tool | Version | Checker | Description | 
|---|---|---|---|
| 
 | 
 | Could report possible violations of this rule merely by reporting any  | 
...
| CERT C++ Secure Coding Standard | FIO05-CPP. Identify files using multiple file attributes | 
| ISO/IEC TR 24772:2013 | Path Traversal [EWR] | 
| MITRE CWE | CWE-37, Path issue—Slash absolute path CWE-38, Path Issue—Backslash absolute path CWE-39, Path Issue—Drive letter or Windows volume CWE-62, UNIX hard link CWE-64, Windows shortcut following (.LNK) CWE-65, Windows hard link | 
...