Main Content

CERT C: Rec. FIO03-C

Do not make assumptions about fopen() and file creation

Since R2024a

Description

Rule Definition

Do not make assumptions about fopen() and file creation.1

Polyspace Implementation

The rule checker checks for File not opened in exclusive mode.

Examples

expand all

Issue

File not opened in exclusive mode occurs when you open a file for writing without adequate check for whether the file already exists.

For instance, you might be opening a file using the fopen() or fopen_s() function using only the w access specifier:

FILE * fp = fopen(file_name, "w");
If the file already exists, its contents are destroyed.

The checker reports calls to the following functions if they open a file for writing without additional specifications to check if the file already exists. Most functions support opening a file in exclusive mode. In this mode, the file opening fails if the file already exists and returns an error code to indicate the failure. If a file is opened in exclusive mode, the checker assumes that the developer has taken into account the possibility of pre-existing files.

FunctionArgument Checked for Write ModeArgument Checked for Exclusive Mode
fopen()

2nd argument: w access specifier indicates write mode.

3rd argument: x access specifier indicates exclusive mode (supported since C11).

fopen_s()

3rd argument: w access specifier indicates write mode.

3rd argument: x access specifier indicates exclusive mode (supported since C11).

open() – POSIX® function

2nd argument: O_CREAT bit mask indicates write mode.

2nd argument: O_EXCL bit mask indicates exclusive mode.

createFile() – Win32API function

2nd argument: GENERIC_ALL or GENERIC_WRITE bit mask indicates write mode.

5th argument: CREATE_NEW or CREATE_ALWAYS bit mask indicates that the user has given due consideration to the possibility of pre-existing files.

The checker also does not report calls to file opening functions if they open a file in append or truncate mode.

Risk

Without adequate checks, if the file opened for writing already exists, its contents are destroyed.

Fix

When opening a file for writing, allow for the possibility that the file already exists. Depending on the function that you use for file opening, you can perform appropriate checks for existing files:

  • When using fopen() or fopen_s(), check if a file already exists. If the file exists, open the file using the access specifier a (append mode) or r+ (read/write mode that requires a file to exist).

  • When using fopen_s(), since C11, you can open the file using the access specifier wx (write mode that causes failure if the file exists). If the file opening fails, perform appropriate actions to prevent overwriting of the file.

You can follow similar fixes for other file-opening functions.

Example – Opening File for Writing Without Adequate Checks
#include <stdio.h>

void readFile(char *fileName) {
    FILE *fptr;

    // Open file
    int errorCode = fopen_s(&fptr, fileName, "w"); // Noncompliant
    if (errorCode != 0) {
        // Handle error
    }
}

In this example, a file is opened using fopen_s() with the w access specifier (write mode). If the file already exists, the file opening action destroys previous contents of the file.

Correction — Open File in Exclusive Mode and Check for Errors

One possible correction is to open the file with the wx access specifier (write mode with exclusive access). In this mode, if the file already exists, the file opening action fails and returns an error code that can be checked for appropriate error handling.

#include <stdio.h>
#include <errno.h>

void readFile(char *fileName) {
    FILE *fptr;

    // Open file
    int errorCode = fopen_s(&fptr, fileName, "wx"); // Compliant
    if (errorCode != 0) {
        // Handle error
    }
}

Check Information

Group: Rec. 09. Input Output (FIO)

Version History

Introduced in R2024a


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.