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

Compare with Current View Page History

« Previous Version 8 Next »

According to its C99 definition, the effect of calling remove() on a file is defined by the implementation. Therefore, care must be taken when remove() is called on an open file. It is often the case that calling remove on a file that is open can help mitigate a file input/output race condition, but the underlying implementation needs to be understood before doing so can be considered secure. To be strictly conforming and portable, however, remove() should not be called on an open file.

Non-Compliant Code Example

The following non-compliant code illustrates a case where a file is removed after it is first opened.

#include <stdio.h>

int main(int argc, char* argv) {
  FILE* first;
  FILE* second;

  char buf1[10];
  char buf2[10];

  int i;

  first = fopen("a.in", "r");

  if (remove("a.in") == -1) {
    printf("Remove Failed\n");
  } else {
    printf("Remove Success\n");
  }

  second = fopen("a.in", "w");
  if (second) {
    printf("Good OPEN\n");
  } else {
    printf("Bad OPEN\n");
  }

  for (i = 0; i < 10; i++) {
    buf2[i] = 'Q';
  }
  fwrite(buf2, sizeof(char), 9, second);
  fflush(second);

  fread(buf1, sizeof(char), 9, first);
  buf1[9] = '\0';
  buf2[9] = '\0';

  printf("First: %10s\n", buf1);

  printf("Second: %10s\n", buf2);
}

Contents of a.in:

AAAAAAAAA

Output from a Red Hat Linux Distribution:

Remove Success
Good OPEN
First: AAAAAAAAA
Second: QQQQQQQQQ

Output from a Cygwin session (Windows XP):

Remove Failed
Good OPEN
15568 [main] rule11 5048 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack)
Segmentation fault (core dumped)

As shown above, the code worked as intended for the Red Hat Linux Distribution but did not work in Cygwin. For the code to be completely portable and conform to the C99 standard, the call to remove() needs to be eliminated.

Compliant Solution

This compliant solution eliminated the call to remove() because the program is intended to run on all platforms.

#include <stdio.h>

int main(int argc, char* argv) {
  FILE* first;
  FILE* second;

  char buf1[10];
  char buf2[10];

  int i;

  first = fopen("a.in", "r");
  second = fopen("a.in", "w");
  if (second) {
    printf("Good OPEN\n");
  } else {
    printf("Bad OPEN\n");
  }

  for (i = 0; i < 10; i++) {
    buf2[i] = 'Q';
  }
  fwrite(buf2, sizeof(char), 9, second);
  fflush(second);

  fread(buf1, sizeof(char), 9, first);
  buf1[9] = '\0';
  buf2[9] = '\0';

  printf("First: %10s\n", buf1);

  printf("Second: %10s\n", buf2);
}

Risk Assessment

Calling remove() on an open file may cause abnormal termination if the closed file is written to or read from, but most implementations allow for remove() to be called on an open file without a problem.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FIOxx-A

1 (low)

1 (low)

2 (medium)

P2

L3

References

[[ISO/IEC 9899-1999:TC2]] Section 7.19.4.1, "The remove function"

  • No labels