You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 59 Next »

Opening a file that is already open has implementation-defined behavior, according to the C Standard, subclause 7.21.3, paragraph 8 [ISO/IEC 9899:2011]:

Functions that open additional (nontemporary) files require a file name, which is a string. The rules for composing valid file names are implementation-defined. Whether the same file can be simultaneously open multiple times is also implementation-defined.

Some platforms may forbid a file simultaneously being opened multiple times, but platforms that allow it may facilitate dangerous race conditions. This is because it is possible for an open file to be moved or deleted on many platforms. If a program re-opens a file using the same pathname, there is no guarantee that the same file is being accessed.

Noncompliant Code Example

This noncompliant code example logs the program's state at runtime:

#include <stdio.h>
 
void do_stuff(void) {
  FILE *logfile = fopen("log", "a");
  if (logfile == NULL) {
    /* Handle error */
  }

  /* Write logs pertaining to do_stuff() */
  fprintf(logfile, "do_stuff\n");
}

int main(void) {
  FILE *logfile = fopen("log", "a");
  if (logfile == NULL) {
    /* Handle error */
  }

  /* Write logs pertaining to main() */
  fprintf(logfile, "main\n");

  do_stuff();
 
  fclose(logfile);
  return 0;
}

However, the file log is opened twice simultaneously. The result is implementation-defined and potentially dangerous.

Implementation Details

On a Linux machine running GCC 4.3.2, this program produces

do_stuff
main

which does not indicate the order in which data was logged.

Compliant Solution

In this compliant solution, a reference to the file pointer is passed as an argument to functions that need to perform operations on that file. This reference eliminates the need to open the same file multiple times.

#include <stdio.h>
 
void do_stuff(FILE *logfile) {
  /* Write logs pertaining to do_stuff() */
  fprintf(logfile, "do_stuff\n");
}

int main(void) {
  FILE *logfile = fopen("log", "a");
  if (logfile == NULL) {
    /* Handle error */
  }

  /* Write logs pertaining to main() */
  fprintf(logfile, "main\n");

  do_stuff(logfile);
 
  fclose(logfile);
  return 0;
}

Implementation Details

On a Linux machine running GCC 4.3.2, this program produces

main
do_stuff

which matches the order in which logging occurred. This output assumes that the log file was not moved or deleted between the twop calls to fopen().

Automated Detection

Tool

Version

Checker

Description

LDRA tool suite

9.7.1

75 D

Fully implemented

Risk Assessment

Simultaneously opening a file multiple times can result in abnormal program termination or data integrity violations.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FIO31-C

Medium

Probable

High

P4

L3

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

 Bibliography

[ISO/IEC 9899:2011Subclause 7.21.3, "Files"

 


 

  • No labels