The rename()
function has the following prototype:
int rename(const char *old, const char *new); |
If the file pointed to by new
exists prior to a call to rename()
, the behavior is implementation-defined. Therefore, care must be taken when using rename()
.
In the following non-compliant code, a file is renamed to another file using rename()
.
/* program code */ const char *old = "oldfile.ext"; const char *new = "newfile.ext"; if (rename(old, new) != 0) { /* Handle rename failure */ } /* program code */ |
However, if newfile.ext
already existed, the result is undefined.
This compliant solution first checks for the existence of the new file before the call to rename()
. Note that this code contains an unavoidable race condition between the call to fopen()
and the call to rename()
.
/* 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 */ |
Using rename()
without caution leads to undefined behavior, possibly resulting in a file being unexpectedly overwritten.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
FIO10-A |
2 (medium) |
2 (probable) |
2 (medium) |
P8 |
L2 |
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.9.4.2, "The {{rename}} function" |
[|IO09-A. fflush() should be called after writing to an output stream if data integrity is important
*[|02. Declarations
and Initialization (DCL)]* *[!CERT
C Secure Coding Standard^button_arrow_right.png!|DCL04-A. Take care when
declaring more than one variable per declaration]*