We talked about file conditions and time of chapter, time of use, file accesses and things like this. There's a whole body of work on this. But what about non-file race conditions? How do those work? Are they a threat? Well the short answer is yes, they are a threat. The problem here is asynchronicity. Within a single process, you're going to have a series of asynchronous events, interrupts, or exception handling. The trick here is to have a second process manipulate things so that the expected path of execution when you're handling an exception is not the one that the process takes. Let me give you an abstract example and then I'll give you a couple of very concrete examples. If you look at the slide Another Race Condition, this shows a Signal Handler. And the signal handler says, okay first, we're going to check the effective UID of the process. If it's not root, then we're going to do one thing. If it is root, then we're going to do something else, presumably, because root can do more of the correction than the ordinary user can. Then in the Program, we have the next two lines. Get a UID gets the effective UID and then we will set the effective UID to what get a UID says. Now the window here is between the assignment of the UID to EUID and the completion of the setuid system call. If the signal arrives before setuid is called, then the signal handler will act not as root which is what you want. However, if it arrives during the setuid call, that's interruptible. So what happens is you get the interrupt. You go up, and you see the effect of UID and you act not as root. But then when you return, you exit from the setuid call without presenting the UID. So that's an example of a race condition. Here's another one, and this one drove people crazy until they figured out what was going on. Everyone thought it was a security problem. It sure looked like one but it turned out it wasn't. The largest FTP server in the world is run on FreeBSD system because of its reliability. And it turned out they were getting all sorts of strange things in the log, essentially, FTP clients where the server was boarding. So there was a problem, they didn't know what it was. So let's talk for a minute about how FTP works. When you type an interrupt, to interrupt the file transfer or whatever, the client immediately generates a command called ABOR, A-B-O-R, and sets the urgent flag and then sends it over to the server. ABOR means abort current operation. In other words, stop sending me the data. The urgent means, "Hey, handle this immediately. Don't wait, don't put it into the queue of ordered FTP commands. Do it now." The FTP client would then close the connection because when the abort comes in, then the server would close the connection. Now this cost us two things. When that abort with the urgent flag set reaches the server, it generates a SIGURG signal. An urgent signal, SIGURG, which causes a jump to any of our hand to interrupt the handler. When the server detects that the client has closed the pipe, client has closed the connection, that generates a SIGPIPE, which goes to another signal handler, and the two conflict. The FTP server has the real UID as root. It has to run this route because when you log in on an FTP server, it's going to drop privileges to whoever you login as. Okay. So basically, you login, the server authenticates you. When it does the authentication, it's running as root. Then it spawns a child, drops privileges to your UID and takes off. Here's the problem. The SIGPIPE, when it comes in the closing, the server immediately gets back the effective UID of root and writes an entry to a file indicating the connection is done, users logged off and then it calls exit. No problem there. But what happens when the urgent command comes in as a interrupt? So it basically causes the FTP server to immediately return to the command loop and wait for new command. What happens if the two conflict? Well, SIGPIPE is called first, occurs first and gets to the exit call. You're done. The SIGURG version is ignored. But, if the urgent signal arrives before the close, before the SIGPIPE, there's no problem as well because it returns the command loop then the SIGPIPE takes you to the exception, the handler that closes everything down. But what happens if you're handling the SIGPIPE in that interrupt handler and the SIGURG arrives? It turned out that the FTP server did not disable that interrupt. So when the SIGURG arrive, it would interrupt the handling of the SIGPIPE and jump back to the main routine waiting for commands. So in essence, you had an FTP process hanging around but no input coming into it. That was what caused the alarm, the system administrators saw an abnormally large number of FTP servers just hanging around in the process table not doing anything. They were afraid someone was poking at the system trying to break in and creating all of these. It turned out to be a race condition that was not being exploited for security purposes. Needless to say, of course, it got fixed. But this shows that race conditions can occur with signals as well. This occurs also with communications when you're doing multithreading and so forth.