Path: utzoo!mnetor!uunet!husc6!cmcl2!brl-adm!adm!mouse@larry.mcrcim.mcgill.edu From: mouse@larry.mcrcim.mcgill.edu (der Mouse) Newsgroups: comp.unix.wizards Subject: Re: Writing to A NON-Existing File in \"C\" Message-ID: <13175@brl-adm.ARPA> Date: 29 Apr 88 04:31:00 GMT Sender: news@brl-adm.ARPA Lines: 73 >>> 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@mcgill-vision.uucp arpa: mouse@larry.mcrcim.mcgill.edu