The rename()
function has the following prototype:
int rename(const char *old, const char *new);
If the file referenced by new
exists prior to calling rename()
, the behavior is implementation-defined. For portability, you must ensure that the file referenced by new
does not exist when rename()
is invoked.
Non-Compliant Code Example
In this non-compliant code example, a file is moved using rename()
.
/* program code */ const char *old = "oldfile.ext"; const char *new = "newfile.ext"; if (rename(old, new) != 0) { /* Handle rename failure */ } /* program code */
If newfile.ext
exists at the time of the call to rename()
, the result is implementation-defined.
Compliant Solution
This compliant solution checks for the existence of the new file before callling rename()
. This code contains an unavoidable race condition between the call to fopen()
and the call to rename()
. Consequently, this code can only be safely executed within a secure directory.
/* program code */ const char *old = "oldfile.ext"; const char *new = "newfile.ext"; FILE *file = fopen(new, "r"); if (file != NULL) { fclose(file); if (rename(old, new) != 0) { /* Handle remove failure */ } } else { /* handle error condition */ } /* program code */
Risk Assessment
Calling rename()
has implementation-defined behavior when the new file name refers to an existing file. Incorrect use of rename could result in a file being unexpectedly overwritten or other unexpected behavior.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
FIO10-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
[[ISO/IEC 9899-1999]] Section 7.9.4.2, "The rename
function"
FIO09-A. fflush() should be called after writing to an output stream if data integrity is important 09. Input Output (FIO) FIO11-A. Take care when specifying the mode parameter of fopen()