Writing to A NON-Existing File in \"C\"
der Mouse
mouse at larry.mcrcim.mcgill.edu
Fri Apr 29 14:31:00 AEST 1988
>>> I propose enclosing the whole mess between two stat's, and testing
>>> whether the vital statistics match.
>> Well, you have to be very careful, and even then, I don't think it's
>> possible to get it right. You can make the window much harder to
>> hit, but I don't think it's possible to get rid of it entirely.
> My idea is more explicitly
> stat(path,&before)
> if (access(path,how) == 0) { /*OK*/
> fd = open(path,mode);
> stat(path,&after);
> [compare after.xxx and before.xxx for appropriate xxx]
> }
> [later in letter] Any problems with this approach?
Yes. Suppose we pull a switch immediately before and after the open().
You can't catch it, and can easily wind up opening the wrong file.
Specifically:
user does program does
% touch myfile.blah
% setuidpgm myfile.blah
stat(path,&before)
if (access(path,how) == 0) { /*OK*/
% mv myfile.blah myfile.save
% ln -s /etc/passwd myfile.blah
fd = open(path,mode);
% rm -f myfile.blah
% mv myfile.save myfile.blah
stat(path,&after);
[compare after.xxx and before.xxx for appropriate xxx]
}
(Of course, those wouldn't actually be typed commands; I'm just using
the commands to indicate the operations being performed.) This is why
I recommend doing fstat() on the file descriptor returned by open(), to
ensure that the file you really opened is the one you were stat()ing.
But that's vulnerable too; think about something similar to the above
with the secure file in place at the beginning, replaced with an
innocuous file for the access() to see.
(You can see why I said the window is "much" harder to hit. The bad
guy must time two operations exactly right instead of just one, and the
interval between the two is very short.)
> Good things to check would be inode number and creation date.
Do any recent systems maintain a creation date? 4.[23]BSD doesn't.
(st_ctime is the inode-change time, not the creation time.)
> Neither can easily be faked, except thru acces to the raw device.
If I wanted to patch a ctime field, I'd much rather change the clock
and touch the file than meddle with the raw disk.
> If [the file being open()ed] doesn't already exist, the job is a bit
> harder.
I claim it's impossible if the user has write access to any of the
ancestors of the directory the file is to be created in.
> BTW, while we're talking windows, mktemp et al suffer as well.
Hence mkstemp(3).
der Mouse
uucp: mouse at mcgill-vision.uucp
arpa: mouse at larry.mcrcim.mcgill.edu
More information about the Comp.unix.wizards
mailing list