...
The following non-compliant code example creates a file with some hard coded filename
file_name
(presumably in a shared directory such as /tmp
or C:\Temp
).
Code Block |
---|
|
char filenamefile_name[] = /* hard coded string */;
FILE *fp = fopen(filenamefile_name, "wb+");
if (fp == NULL) {
/* Handle Error */
}
|
...
Code Block |
---|
|
char filenamefile_name[L_tmpnam];
FILE* fp;
if (!tmpnam(filenamefile_name)) {
/* Handle Error */
}
/* A TOCTOU race condition exists here */
fp = fopen(filenamefile_name, "wb+");
if (fp == NULL) {
/* Handle Error */
}
|
...
Wiki Markup |
---|
This next non-compliant code example attempts to remedy the problem by using the POSIX {{open()}} function, and providing a mechanism to indicate whether an existing file has been opened for writing or a new file has been created \[[Open Group 04|AA. C References#Open Group 04]\]. If the {{O_CREAT}} and {{O_EXCL}} flags are used together, the {{open()}} function fails when the file specified by {{filenamefile_name}} already exists. To prevent an existing file from being opened and truncated, include the flags {{O_CREAT}} and {{O_EXCL}} when calling {{open()}}. |
Code Block |
---|
|
char filenamefile_name[L_tmpnam];
int fd;
if (!(tmpnam(filenamefile_name))) {
/* Handle Error */
}
/* A TOCTOU race condition exists here */
fd = open(filenamefile_name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0600);
if (fd < 0) {
/* Handle Error */
}
|
This call to open()
fails whenever filename
file_name
already exists, including when it is a symbolic link. This is secure, but a temporary file is presumably still required. Unfortunately, the method used by tmpnam()
to generate file names is not guaranteed to be unpredictable, which leaves room for an attacker to guess the file name ahead of time.
...
Code Block |
---|
|
char filenamefile_name[L_tmpnam_s];
int fd;
if (tmpnam_s(filenamefile_name, L_tmpnam_s) != 0) {
/* Handle Error */
}
/* A TOCTOU race condition exists here */
fd = open(filenamefile_name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0600);
if (fd < 0) {
/* Handle Error */
}
|
...
Code Block |
---|
|
char filenamefile_name[] = "tmp-XXXXXX";
int fd;
if (!mktemp(filenamefile_name)) {
/* Handle Error */
}
/* A TOCTOU race condition exists here */
fd = open(filenamefile_name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0600);
if (fd < 0) {
/* Handle Error */
}
|
...