...
To ensure that a program is reading from an intended file, and not a different file in another directory, it is necessary to check for the existence of symbolic or hard links.
Non-Compliant Code Example (POSIX)
This non-compliant code example open the file specified by the string "/home/rcs/.conf" for read/write exclusive access, and then writes user supplied data to the file.
...
If the process is running with elevated privileges, an attacker can exploit this code, for example, by creating a link from .conf to the {{/etc/passwd }} authentication file. The attacker can then overwrite data stored in the password file to create a new root account with no password. As a result, this attack can be used to gain root privileges on a vulnerable system.
Non-Compliant Code Example (POSIX)
The only function available on POSIX systems to collect information about a symbolic link rather than its target is the lstat() function. This non-compliant code example uses the lstat() function to collection information about the file, and then checks the st_mode field to determine if the file is a symbolic link.
| Code Block | ||
|---|---|---|
| ||
struct stat lstat_info;
int fd;
if (lstat("some_file", &lstat_info) == -1) {
/* handle error */
}
if (!S_ISLNK(lstat_info.st_mode)) {
if ((fd = open("some_file", O_EXCL|O_RDWR, 0600)) == -1) {
/* handle error */
}
}
write(fd, userbuf, userlen);
|
Non-Compliant Code Example (POSIX)
This non-compliant code example eliminates the race condition by:
...
| Wiki Markup |
|---|
Tihs eliminate the TOCTOU condition because {{fstat()}} is applied to file descriptors, not file names, so the file passed to {{fstat()}} must be identical to the file that was opened. The {{lstat()}} function does not follow symbolic links, but {{fstat()}} does. Comparing modes using the {{st_mode}} field is sufficient to check for a symbolic link.
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()}} \[[FIO05-A|FIO05-A. Identify files using multiple file attributes]\]. |
Risk Assessment
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
FI008 POS01-C A | 2 (highmedium) | 3 (unlikelylikely) | 2 (medium) | P12 | L1 |
Examples of vulnerabilities resulting from the violation of this recommendation can be found on the CERT website.
References
| Wiki Markup |
|---|
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.19.7.2, "The fgets function" \[[Seacord 05|AA. C References#Seacord 05]\] Chapter 7, "File I/O" |