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.