...
| Code Block | ||||
|---|---|---|---|---|
| ||||
char *filename = /* file name */;
char *userbuf = /* user data */;
unsigned int userlen = /* length of userbuf string */;
struct stat lstat_info;
int fd;
/* ... */
if (lstat(filename, &lstat_info) == -1) {
/* Handle error */
}
if (!S_ISLNK(lstat_info.st_mode)) {
fd = open(filename, O_RDWR);
if (fd == -1) {
/* Handle error */
}
}
if (write(fd, userbuf, userlen) < userlen) {
/* Handle error */
}
|
This code contains a time-of-check-, time-of-use (TOCTOU) race condition between the call to lstat() and the subsequent call to open() because both functions operate on a file name that can be manipulated asynchronously to the execution of the program. (See recommendation FIO01-C. Be careful using functions that use file names for identification.)
...
- calling
lstat()on the file name. - calling
open()to open the file. - calling
fstat()on the file descriptor returned byopen(). - comparing the file information returned by the calls to
lstat()andfstat()to ensure that the files are the same.
| Code Block | ||||
|---|---|---|---|---|
| ||||
char *filename = /* file name */;
char *userbuf = /* user data */;
unsigned int userlen = /* length of userbuf string */;
struct stat lstat_info;
struct stat fstat_info;
int fd;
/* ... */
if (lstat(filename, &lstat_info) == -1) {
/* handle error */
}
fd = open(filename, O_RDWR);
if (fd == -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) {
if (write(fd, userbuf, userlen) < userlen) {
/* Handle Error */
}
}
|
...
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 recommendation FIO05-C. Identify files using multiple file attributes.)
...
Tool | Version | Checker | Description | section|
|---|---|---|---|---|
Compass/ROSE |
|
| | Section | Can detect some violations of this rule. In particular, it ensures that calls to |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
ISO/IEC 9899:1999] Section 2011 Section 7.1921, "Input/output <stdio.h>"
MITRE CWE: CWE-363, "Race Condition Enabling Link Following"
MITRE CWE: CWE-365, "Race Condition in Switch"
...
Sources
[Dowd 2006] Chapter 9, "UNIX 1: Privileges and Files"
[Open Group 2004] lstat(), fstat(), open()
[Seacord 2005a] Chapter 7, "File I/O"
...