Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Securely creating temporary files in a shared directory is error prone and dependent on : the version of the C runtime library used, the operating system, and the file system. Code that works for a locally mounted file system, for example, may be vulnerable when used with a remotely mounted file system.

...

If /tmp/some_file already exists, then that file is opened and truncated. If /tmp/some_file is a symbolic link, then the target file referenced by the link is truncated.

...

Wiki Markup
The {{fopen()}} function does not indicate ifwhether an existing file has been opened for writing or a new file has been created. However, the {{open()}} function as defined in the Open Group Base Specifications Issue 6 \[[Open Group 04|AA. C References#Open Group 04]\] provides such a mechanism.  If the {{O_CREAT}} and {{O_EXCL}} flags are used together, the {{open()}} function fails when the file specified by {{file_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
bgColor#FFCCCC
int fd = open("/tmp/some_file", O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0600);

This call to open() fails whenever /tmp/some_file already exists, including when it is a symbolic link. This is a good thing, but a temporary file is presumably still required. One approach that can be used with open() is to generate random file names filenames and attempt to open() each until a unique name is discovered. Luckily, there are predefined functions that perform this function.

Wiki Markup
Care should be observed when using {{O_EXCL}} with remote file systems, as it does not work with NFS version 2. NFS version 3 added support for {{O_EXCL}} mode in {{open()}}; see IETF RFC 1813 \[[Callaghan 95|AA. C References#Callaghan 95]\], in particular the {{EXCLUSIVE}} value to the {{mode}} argument of {{CREATE}}. 

Non-Compliant Code Example: tmpnam()

Wiki Markup
The C99 {{tmpnam()}} function generates a string that is a valid filefilename name and that is not the same as the name of an existing file \[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\]. Files created using strings generated by the {{tmpnam()}} function are temporary in that their names should not collide with those generated by conventional naming rules for the implementation.  The function is potentially capable of generating {{TMP_MAX}} different strings, but any or all of them may already be in use by existing files.  If the argument is not a null pointer, it is assumed to point to an array of at least {{L_tmpnam}} chars; the {{tmpnam()}} function writes its result in that array and returns the argument as its value.

...

Wiki Markup
Unfortunately, this solution is still non-compliant because it violates \[[FIO32-C|FIO32-C. Temporary file names must be unique when the file is created]\], \[[FI040-C|FI040-C. Temporary files must be opened with exclusive access]\], \[[FI041-C|FI041-C. Temporary files must have an unpredictable name]\], and \[[FI042-C|FI042-C. Temporary files must be removed before the program exits]\]. 

Non-Compliant Code Example: tmpnam_s() (ISO/IEC TR 24731-1)

Wiki Markup
The TR 24731-1 {{tmpnam_s()}} function generates a string that is a valid filefilename name and that is not the same as the name of an existing file \[[ISO/IEC TR 24731-2006|AA. C References#SO/IEC TR 24731-2006]\]. The function is potentially capable of generating {{TMP_MAX_S}} different strings, but any or all of them may already be in use by existing files and thus not be suitable return values.  The lengths of these strings must be less than the value of the {{L_tmpnam_s}} macro.

...

Wiki Markup
This solution is also non-compliant because it violates \[[FIO32-C|FIO32-C. Temporary file names must be unique when the file is created]\] and \[[FI042-C|FI042-C. Temporary files must be removed before the program exits]\]. 

Non-Compliant Code Example: mktemp()/open() (POSIX)

The POSIX function mktemp() takes a given file name filename template and overwrites a portion of it to create a file namefilename. The template may be any file name filename with some number of 'X's Xs appended to it , (for example, /tmp/temp.XXXXXX). The trailing 'X's Xs are replaced with the current process number and/or a unique letter combination. The number of unique file names filenames mktemp() can return depends on the number of 'X's Xs provided.

Code Block
bgColor#FFcccc
...
int fd;
char temp_name[] = "/tmp/temp-XXXXXX";

if (mktemp(temp_name) == NULL) {
  /* Handle Error */
}
if ((fd = open(temp_name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0600)) == -1) {
  /* Handle Error */
}
...

Wiki Markup
This solution is also non-compliant because it violates \[[FIO32-C|FIO32-C. Temporary file names must be unique when the file is created]\] and \[[FI042-C|FI042-C. Temporary files must be removed before the program exits]\]. 

Include Page
c:FIO39 CS mkstemp
c:FIO39 CS mkstemp

...