I wanted to close with a puzzle, and here's the puzzle. There was a program called Mathematica, that does advanced mathematics and it turns out it creates temporary files in a directory /tmp/MathLink. It just creates those files and overwrites existing ones in the directory. The first question is, how would you exploit this to clobber someone's start-up file? I'll give you a minute to think about that. Remember the goal here is to overwrite someone else's file. The blue code beneath the question shows you this. You create a directory called MathLink, which you own. Then you do a symbolic link to one of the files that you know will be created there. If it's on the same file system, you could make the link direct not symbolic. Anyway, then when Mathematica runs, it's going to open that file. It will do so because on some systems it is root privileges just overwrite what it's in the.gshmm, which will overwrite what's in the cshrc file, so you're done. Now the next puzzle is how would you fix this? I might give you a minute to think about that. There are two ways to fix this. The hard way is to check that the file is in fact owned by a root or owned by whoever is running Mathematica. I did in the example I gave earlier. What will happen is no it's not because it's owned by a victim. A second way to handle this which is actually much cheaper, it's just delete the file. If a file exists and Mathematica wants to write it, delete the existing one. It's an old file, it's just lying around there not doing anything. If you delete it, you're not going to delete the victim start-up file because that's a link. What's in the MathLink directory is a link to that file, so you just delete it. By the way, when you do this if it's a symbolic link, make sure you delete the symbolic link and not the referent. On all systems that I know of, Linux and FreeBSD for example, unlink will actually unlink the symbolic link but double-check your manual and that solves the problem. So this leads to two key ideas. Probably the most fundamental is that a race condition requires two processes. No single process can ever have a race condition, it requires two processes, two threads, whatever. It also requires that the environmental condition holds, so it's not just the property of the process, it's also a property of the environment in which the process runs. The programming condition must hold within the process. The other process has to hit that window and do something within that window. This by the way leads to the second observation which is, when you're doing checking and then using, check is close to the use as possible. If you can do it in the same system call, so much the better. That's why when we talked about spawning subprocesses, when the subprocess started up, it had the effect of UID of the real person who was running the program. So the access check, the appropriate access check is performed in the open system call, which for all intents and purposes is indivisible with respect to this problem. Within that window, you want to make sure that the conditions can't change and that's where the environmental condition comes in. Because that checks to see whether or not the only ones who can make changes are trusted people.