Friday, January 6, 2012

Mutexes, Semaphores, Security, oh my!

A mutex is a computer science concept known as a mutual exclusion. This is used to protect specific components from being accessed or modified by multiple threads or processes at the same time.  These resources could be memory, databases, or some other data structure.

When a process needs to access a protected resource, it first must make sure the resource is not already in use. Typically this is performed by checking the value of a counter variable. This counter variable has a binary value. If the value is 0, then the resource is not in use and the process may go ahead and use the resource. However, if the value is 1, the resource has already been "locked" by another process and the requesting process must wait until the resource becomes available. Once the process is able to use the resource, it increments the binary variable so that no other process can use it. After the process is done working with the resource it subtracts 1 from the counter variable. Other processes would now be able to access the resource.

Imagine that your favorite pub has had some issues with their restroom. Some punks keep making a mess in there. The management decides to keep the door locked at all times. The bartender has the only key.

During a normal night, patrons that need to use the restroom (resource) ask the bartender (mutex) for the key(binary variable). Only those with the key have the ability to use the restroom. As the patron enters the bathroom, the door automatically locks behind them. Once the patron is done in the restroom, they bring the key back to the bartender.

If someone needs to use the restroom while someone is already in there, the bartender tells them to wait at the end of the bar in a line (queue). Once the patron returns the key, the bartender will give the first person in the line(queue) the key (binary variable). This continues until no one else needs to use the restroom.



Semaphores are pretty much the the same as mutex's except that they are not binary. Multiple resources can be handled at the same time.

Take the example from above, except instead of one bathroom, the pub adds two additional bathrooms. Now, when patrons ask the bartender for the key, he has three to give out. Each restroom can still only have one patron at a time, however. Each patron must select from a restroom that is not already occupied.

Instead of using a binary variable, semaphores use an integer variable. The maximum number of resources that can be use at any one time is the variables upper limit. Each time a process requests access to a resource, the semaphore subtracts 1 from this counter variable.

When the counter variable become a negative value, it tells any processes that request a resource to wait until that variable is no longer negative.

Semaphores also have the ability to control the flow of execution. You may only allow a process to access a resource after a condition(s) are met.

Now that we've got the concept of a mutex and a semaphore, lets think about the possible issues.

What would happen if a patron really needed to go to the restroom and didn't wait to get a key from the bartender? Lets say, this patron just ran into the restroom behind someone else before the door closed. What would happen?

There would probably be a fight and possibly someone needing to do laundry.

In software terms, this condition could possible lead to a crash of the application or the resource that both threads accessing being destroyed or corrupted.

Lets say that an application has two processes. The first process handles authentication and the second retrieves sensitive data from a database and returns it to an authenticated user.

In a normal situation, the authentication thread will request access to the data and lock it until proper authentication is give. Once the user enters the correct password, the initial thread releases the lock and the second thread is allowed to access the data.

What would happen if somehow that counter variable was changed from a 0 to a 1 before the user enters the correct password? Depending on the code, it could be possible for the sensitive data to be given to an unauthenticated user.

This type of issue is called a race condition. One thread access a resource before it is supposed to. It can lead to very serious software vulnerabilities.

Here are some examples of some real world race conditions:

http://technet.microsoft.com/en-us/security/bulletin/ms11-057
http://xforce.iss.net/xforce/xfdb/66180
http://technet.microsoft.com/en-us/security/bulletin/MS10-006

Here's a video of Allen Downey speaking about semaphores (and free books) and his book on the subject

http://www.youtube.com/watch?v=RaEUw107dpg
http://greenteapress.com/semaphores/