...
Code Block |
---|
|
char *file_name;
FILE *fp;
/* initialize file_name */
fp = fopen(file_name, "w");
if (!fp) {
/* handleHandle error */
}
|
Noncompliant Code Example: fopen_s()
(ISO/IEC TR 24731-1)
...
Code Block |
---|
|
char *file_name;
FILE *fp;
/* initialize file_name */
errno_t res = fopen_s(&fp, file_name, "w");
if (res != 0) {
/* handleHandle error */
}
|
Compliant Solution: open()
(POSIX)
Wiki Markup |
---|
The {{open()}} function, as defined in the Open Group Base Specifications Issue 6 \[[Open Group 04|AA. C References#Open Group 04]\], is available on many platforms and provides finer control than {{fopen()}}. In particular, {{fopen()}} accepts the {{O_CREAT}} and {{O_EXCL}} flags. When used together, these flags instruct the {{open()}} function to fail if the file specified by {{file_name}} already exists. |
Code Block |
---|
|
char *file_name;
int new_file_mode;
/* initialize file_name and new_file_mode */
int fd = open(file_name, O_CREAT | O_EXCL | O_WRONLY, new_file_mode);
if (fd == -1) {
/* Handle Errorerror */
}
|
Wiki Markup |
---|
Care should be taken when using {{O_EXCL}} with remote file systems asbecause it does not work with NFS version 2. NFS version 3 added support for {{O_EXCL}} mode in {{open()}}. IETF RFC 1813 defines the {{EXCLUSIVE}} value to the {{mode}} argument of {{CREATE}} \[[Callaghan 95|AA. C References#Callaghan 95]\]. |
...
The GNU C library defines an additional character for use in opentype
: the character 'x
' insists on creating a new fileâ”if a file filename
already exists, fopen
fails rather than opening it. If you use 'x
' you are guaranteed that you will not clobber an existing file. This is equivalent to the O_EXCL
option to the open
function.
This compliant solution uses the x
mode character to instruct fopen ()
to fail rather than open an existing functions.
Code Block |
---|
|
char *file_name;
/* initialize file_name */
FILE *fp = fopen(file_name, "wx");
if (!fp) {
/* Handle Errorerror */
}
|
Use of this (non-portablenonportable) extension allows for the easy remediation of legacy code.
...
Code Block |
---|
|
char *file_name;
int new_file_mode;
FILE *fp;
int fd;
/* initialize file_name and new_file_mode */
fd = open(file_name, O_CREAT | O_EXCL | O_WRONLY, new_file_mode);
if (fd == -1) {
/* Handle Errorerror */
}
fp = fdopen(fd, "w");
if (fp == NULL) {
/* Handle Errorerror */
}
|
Risk Assessment
The ability to determine if an existing file has been opened or a new file has been created provides greater assurance that a file other than the intended file is not acted upon.
...