今天春天
今天春天

Reputation: 993

fileno for closed file

I have a function like this which aims to read a file:

int foo(FILE* f)

I want to use flock in order to prevent TOCTTOU. flock requires a file descriptor as an integer. I can get this using fileno(file). The implementation of foo therefore might look like this:

int foo(FILE* f) {
  if(!f) return -1;
  int fd = fileno(f);
  if(fd < 0) return -1;
  flock(fd, LOCK_EX);
  //do all the reading stuff and so on.
} 

However, the evil user might do something like this:

FILE* test;
test = fopen("someexistingfile.txt", "r");
fclose(test);
foo(test);

Then I have a problem because fileno will do invalid reads according to valgrind because it assumes that the file is open.

Any ideas on how to check whether the file is closed?

Upvotes: 0

Views: 562

Answers (1)

C11 n1570 7.21.3p4

  1. A file may be disassociated from a controlling stream by closing the file. Output streams are flushed (any unwritten buffer contents are transmitted to the host environment) before the stream is disassociated from the file. The value of a pointer to a FILE object is indeterminate after the associated file is closed (including the standard text streams). Whether a file of zero length (on which no characters have been written by an output stream) actually exists is implementation-defined.

After fclose the use of the value of a FILE * in library functions leads to undefined behaviour. The value of the pointer cannot be used safely for anything at all until reassigned.

In other words, you cannot do really anything at all to discern whether the FILE * value you've given refers to a valid open file or not... well except for testing against NULL - if the value of the pointer is NULL it certainly cannot point to an open stream.

Upvotes: 3

Related Questions