views:

150

answers:

4

I was going through an article today when it mentioned the following:

"We've found many errors over the years. One of the absolute best was the following in the X Window System:

     if(getuid() != 0 && geteuid == 0) {
       ErrorF("Only root");
       exit(1);
     }

It allowed any local user to get root access. (The tautological check geteuid == 0 was intended to be geteuid() == 0. In its current form, it compress the address of geteuid to 0; given that the function exists, its address is never 0)."

The article explained what was wrong with the code but I would like to know what it means to say that "It allowed any local user to get root access". I am not an expert in C but can someone give me an exact context in which this exploit would work? Specifically, what I mean is, lets say I am the local user, how would I get root access if we assume this code to be present somewhere?

For anyone interested in reading the full article, here's the link:

A Few Billion Lines of Code Later: Using Static Analysis to Find Bugs in Real World

+2  A: 

How you would gain access is directly tied to where this flaw is in code.

If you knew exactly where this code was you could explore code paths that could get you to this line of code, and then after examining the consequences of this code do something to exploit the mistaken security level check.

However; this specific test seems pretty hard to exploit. All it does is (incorrectly) check for root access, and if the user doesn't have it, then bail with an error condition.

The subsequent code would have to be audited to see if the fact that non-root users were executing the code could be exploited.

John Weldon
Thank for the explanation. However, I was looking for that one extra point about X getting installed with the setuid bit set.
Legend
+5  A: 

The article means that the code after the if, which was intended to be executed only if it was verified that the user was root, could actually be executed by anyone. To take advantage of it, you look for the branch in the code in which the test is used to check the identity of the user (which the article responsibly does not provide: you have to work a little) and you arrange for it to be executed.

"allowed to get root access" is an ellipsis to describe what happens after the if in the original code. It does not make particular sense in relation with the test because it describe what happens after it.

In other words, the test itself does not make you root. The code after it makes you root. Also, bear in mind that the X server often has to be installed with root owner and setuid bit set, which is the reason why flawed logic in its code is dangerous.

This is not a question about C. It is a question about the Unix security model, which is awfully binary (especially in the older implementations): you have to be root to do anything, so quantities of programs have root owner and setuid bit (caricaturing a little bit).

Pascal Cuoq
Thanks for the detailed explanation.
Legend
A: 

I think this means that the check for root access was not correct and allowed root level processing to continue. How you may have been escalated is not clear in this.

Preet Sangha
A: 

The check geteuid == 0 is always false as geteuid is the name of a function and in this context it evaluates to a pointer that is not NULL. It should have been geteuid() == 0. Note the parenthesis.