Reputation: 993
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
Reputation: 133988
- 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