The Linux Backdoor Attempt of 2003
Hugh Pickens DOT Com writes "Ed Felton writes about an incident, in 2003, in which someone tried to backdoor the Linux kernel. Back in 2003 Linux used 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. But some people didn't like BitKeeper, so a second copy of the source code was kept in CVS. On November 5, 2003, Larry McAvoy 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 a small change to wait4: 'if ((options == (__WCLONE|__WALL)) && (current->uid = 0)) ...' A casual reading makes it look like innocuous error-checking code, but a careful reader would notice that, near the end of the first line, it said '= 0' rather than '== 0' 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 it's a classic backdoor. We don't know who it was that made the attempt—and we probably never will. But the attempt didn't 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. 'Could this have been an NSA attack? Maybe. But there were many others who had the skill and motivation to carry out this attack,' writes Felton. 'Unless somebody confesses, or a smoking-gun document turns up, we'll never know.'"
Unless somebody has proof that somebody was trying to create a back door then stop with all of the "X-Files" shit. It could have been a hacker trying to put that code in. How was the system that hosted the CVS repository managed? Was it hacked? Was there any investigation or was it possibly somebody that did something stupid and now everybody thinks it's somehow tied to the NSA?!?!?
Let's just go forward with what we know and stop the speculation, that is unless somebody has some hard facts like an IP address that belongs to the government or a chain of evidence.
Harrison's Postulate - "For every action there is an equal and opposite criticism"
This has been posted plenty of times on here, and this article has no new information on the backdoor attempt. About the only thing is the spurious claim the NSA was behind hit. Geez.
Each of us has between 10 and 10,000 different code lineages in operation on our desktop.
Single = in an if statement should end in warning and should be considered error in production code. There should be compiler --switch for this.
It's why placing constants on the left of the equality operator is a good idea in C/C++. The whole line then looks suspicious because its constants are on the right, and the first thing you'll think about is bugs involving operator = instead of operator ==. Unfortunately there's a lot of old code that doesn't do this, but it's easy enough for a compiler to issue warnings about operator = in if-statements.
Who ordered that?
The difference between linux and closed source OSs is that on linux you may be able to identify malicious code in the kernel and remedy this situation. For closed source solutions you're truly fucked through and through. You seriously think Microsoft and Apple haven't backdoored their OS ? Just one more reason to stop using closed source software if you value your privacy, your secrets etc...
I am impressed that the kernel team caught that. Kudos!
Signed,
Spartacus
https://app.box.com/WitthoftResume Code: https://github.com/cellocgw
Wrap assignment in parenthesis to explicitly indicate intended behavior. ...
if ((a = b))
Good point. Technically thought, the assignment doesn't return a boolean, it returns a number.
The "if" statement on the other hand treats integer arguments as implicit booleans: if (a != 0) ... that's where the type unsafety lies.
Further investigation determined that someone had apparently broken in electronically to the CVS server and inserted a small change
It was in the description.
I guess compilers are already smart enough to warn about this kind of accident, but sometimes I still wonder if it would have been better to have := for assignment and = for comparison also in C.
Give me an R!
Give me a T!
Give me an F!
Give me an A!
It should be an error in toy languages, yeah.
In C, not so much.
FWIW, assignment doesn't ``return a bool'' but ``is an expression which evaluates to the assigned-to value (an rvalue of appropriate type).''
CLI paste? paste.pr0.tips!
Most compilers do make this at least a warning. It isn't an error because it's a moderately common C-ism to do this in order to assign and check the return value or a function in 1 statement. Particularly if the value is a standard 0 on error or NULL on error return.
I still have more fans than freaks. WTF is wrong with you people?
I, personally don't like 'root' being user number zero.
When I first started using Linux I tried to run a process under a service account by name 'dvrservice'. What actually happened was the process launcher parsed the name 'dvrservice' into an integer, value 0, thereby running the public facing network service as root.
fortunently I detected that before anything bad happend.
It would be more secure, I think, if each install generated a random uid for root, so that instead of (uid = 0) or obfuscated (uid = serviceuid - serviceuid), etc. programs would have to call (uid = getroot()) so that a search/flag for all occurances of that function call could find everything trying to run as root.
But I have no delusions that this change could be reasonably made across Linux at this time, it's not like changing a HOSTS file.
Well, did you even read the entire summary? Where it says that pretty much everything was bypassed?
Getting code into a versioning system without a record of it means you bypassed the whole thing, or the versioning system was crap.
Lost at C:>. Found at C.
I hope the Linux team, which has the security of billions of people in their hands, uses far better security than Felton's article implies. (And for all I know it is.)
The excerpt above suggests that someone happened to notice a change that wasn't pointing to an approval record. What if nobody happened to notice? What if the attacker also created an approval record? And was there a serious effort to find the exploit used and close it, and find the perpetrator?
I hope the Linux kernel's integrity is monitored much more carefully. For example (and I'm just guessing; I don't know much about the Linux kernel), someone could manually validate that every change to the code's fingerprint (and/or the compiled kernel's fingerprint) is legitimate. At ~200 changes/day, one person could do it -- a small investment for something so critical.
The widespread use of Linux makes it an exceptionally valuable target. People will spend a lot of time and money attacking it. It's security needs to be proportional to the threats.
http://linux.slashdot.org/story/03/11/06/058249/linux-kernel-back-door-hack-attempt-discovered
That would be a nightmare in many ways IMHO.
I think it should be a standard constant value, just not 0. Something more unique and immediately distinguishable.
Doesn't GCC warn for this by default? I'm pretty sure I remember getting compiler warnings from it in cases when I deliberately had an assignment operator in an if conditional.
It's FOIA time!
A language and compiler from last decade.
A golden age when only the observant few knew without a doubt that the worlds governments were malignant.
And everybody else thought they were just paranoid loons overdue their Thorazine shots.
5318008?
I don't know how many bits a Linux UID is, I think Windows uses GUIDs (128 bits; but not all unique iirc) so I don't know the odds of a collision, but yeah, it would be a problem if you org assigned standard numbers to service accounts or something...
But if you never referred to accounts by number, only name, and left the numbers to the internal systems...
oh, maybe drive the fundies crazy, UID 666.
I read a booklet at my religious aunts house once that claimed the existance of chmod 666 as part of the proof that computers were going to implement the 'number of the beast'...
But even in C, it should (and does using any reasonable compiler, I think) generate a warning.
Personally, I try to code any comparisons involving literals with the literal on the left (e.g. if(0 == foo)... instead of if(foo == 0)...) so that I get a "lvalue required as left operand of assignment" error if I leave one of the equals signs out. And when I intend an assignment, I do it in a separate statement (e.g. foo = 0; if(0 == foo)...).
On a side note, the compiler folks probably ought to change that error message to "hey idiot, you're doing an assignment when you really mean to do a compare" since that's more likely to be the cause rather than that you intended to assign but just forgot that your identifier wasn't a valid lvalue.
"[Regarding the 'cloud,'] ownership was what made America different than Russia." -- Woz
I always use '-Wall -pedantic' for gcc, and if my code is producing any warnings, I always fix them all.
If the kernel developers had been doing this, they would have seen a big fat warning. For those who still like to use this dubious idiom, putting double parentheses around the assignment make the side effects more explicit to the reader and disables the warning.
That would be a neat attack vector.
user = 'low_priority_user'
Parsed as root, reads like not root.
I should use this sig to advertise my book ISBN-13 : 978-1501515132.
Most of the article is about the backdoor, there is one line mentioning NSA that starts with could, it's one possible suspect among many others so stop getting all ultra-defensive.
You might want to look at your own reaction on this. Would you react the same way if it said "could it have been a Chinese attack?" Are you over-reacting because you want everything to be fair or because you're brainwashed by patriotism?
It doesn't bother me. It bothers all the undisciplined programmers. I program in gates, where everything is a bool.
I should use this sig to advertise my book ISBN-13 : 978-1501515132.
PLEASE scan that booklet! It'll go viral overnight!
I know how C works. C is incompatible with a large swath of humans. Particularly when it comes to malicious obfuscated code.
I should use this sig to advertise my book ISBN-13 : 978-1501515132.
That's the most useless reply ever. "If you can't figure it out yourself, I'm certainly not going to tell you!"
Sounds like you don't know the answer either, but just don't want to admit it.
No, it shouldn't.
It likely should be an error if you're setting it to a constant. That's equivalent to forcing true or false in the if, with a side-effect of changing the value of a variable. I can only see a few very convoluted cases where that would make any sense, and there are far more readable ways to write them.
The old 'if (fp = fopen("foo", "r") )' makes sense, but there's no real reason to write it that way any more. It should at least be a warning.
99.99% of programmers don't need to use single = in a conditional, so add a compiler switch to disallow it as a syntax error instead of just a warning.
Given modern optimizing compilers designed hand-in-hand with chips, probably 99.99999%. Like 3 guys maybe.
(-1: Post disagrees with my already-settled worldview) is not a valid mod option.
"the Linux team was careful enough to notice that that this code was in the CVS repository" Do I win a prize for being careful enough to notice that that?
That doesn't apply when you already know they're out to get you.
"[Regarding the 'cloud,'] ownership was what made America different than Russia." -- Woz
Yep, if no one has seen any aliens, you could assume that they don't exist. BUT, if you see even one alien, you could say that they are everywhere.
Simple math man, 2 = infinity .
If your language returns a boolean from assignment, then it sucks and invites this sort of thing.
if (a = b) ... should always be an error.
Good thing C doesn't have Booleans, then.
It helps to remember that C was intended as a fairly thin layer over assembly. In assembly you can set one register to the value of another, then branch-if-not 0, Two instructions on most platforms. Why should that be an error? Of course, one hopes than on most modern compilers it's a warning.
Socialism: a lie told by totalitarians and believed by fools.
All the criminal activity the NSA has done and continues to do has done nothing but made the entire hardware and software structure of the Internet vulnerable, paving a smooth, superhighway to everyone else in the world that wishes to either destroy modern society or simply steal money from the 99%.
The petard the NSA and Western World will be hoisted upon is one of their own making. (Cylons 1:15)
There's no such thing as 2
I use it all the time in code like:
if(( bytesWritten = write(sock, buf, bytesRemaining)) == ERROR) {
It's an ok to deal with the fact that the BSD socket API is overly verbose and a pain to deal with. The last time I made a mistake accidentally doing = instead of == was a long, long time ago, though. So I'm not sure it's a real problem.
"First they came for the slanderers and i said nothing."
Even if the code had been accepted and committed, it would have been some time before it would have started rolling out into systems. How many people do you know who consistently run the latest Linux kernel? The most popular distros are generally (at least) a few months behind on adopting the latest kernel, so even if this was committed next week it would have likely not shown up in widespread use until the middle of next year at the earliest.
And beyond that, the users that use Linux are likely far less interesting to the NSA than they like to tell themselves to be. Enemies of the state don't generally have an interest in running anything other than windows (which they often steal, so the cost is irrelevant).
Damn_registrars has no butt-hole. Damn_registrars has no use for a butt-hole.
666 is a pretty evil permission actually. Making a file world writable is just asking for trouble. I'm also shocked at the prospect that a Jack Chick type pamphleteer would understand Unix permissions. Those people are usually quite technologically challenged.
I read the internet for the articles.
Versus using a language that's less than 4 years old...what could possibly go wrong?
Unity? Screw that: XFCE. Slashdot Beta? Screw that: SoylentNews. Australis? Screw that: Pale Moon. UX developers DIAF
If it was the NSA, it'd be hard to trace now. Especially as this is going back to 2003, prior to all this excitement. It doesn't matter. It didn't work, and the NSA is suspected of perpetrating more recent attacks at a different level in the chain.
But this example brings up a good point, which is how vulnurable C and C++ code is in general to obfuscation. It is a known security risk and attack vector, but programmers tend to gloss over it, mainly when they can't accept that they are just as capable of making mistakes as the next guy.
"If a nation expects to be ignorant and free in a state of civilization, it expects what never was and never will be."
Am I the only one who is REALLY afraid of aliens trying to backdoor my cornhole?
Here's why the UID is 0 and should stay 0.
In most assembly languages, when you compare against a value, you have use a "compare" instruction that effectively does a subtraction, but throws away the result.
In most CPUs, there is a flags register with a zero (Z) bit, which is flipped whenever a value is loaded that is zero.
When you want to see if something like your accumulator or another register is an arbitrary value like 100, you need to do a "compare 100" and then "branch if equal to whatever..."
If it's zero, you can just load the value and skip the compare step. You get a "free compare" when the value you want to compare against is zero.
So if the superuser is not zero, there will be a performance penalty.
Besides, this dumb shit is C's fault for using = and == as operators. Pascal had it right with := being the assignment operator.
and it would have worked too, if it hadn't been for those meddling kids.
Well if it happened in 2003, then we know it cannot possibly be the NSA. After all, we have been told repeatedly by the mainstream media and by reputable unbiased sites such as our beloved slashdot that the government was 1000% righteous and benevolent from 2001-2008 and only became evil after we elected a socialist anarchist fascist liberal hippie far left islamist atheist democratic dictator to the white house. So clearly, the NSA in 2003 could not have been behind an attempt to insert malicious code into the Linux kernel; and if they somehow were then real Americans had nothing to fear about it anyways!
But of course, they weren't behind it! They couldn't have done it!
Damn_registrars has no butt-hole. Damn_registrars has no use for a butt-hole.
So if one were to grep the source code for "uid = 0" today, I assume that any instances found are legit?
I thought SELinux was a clever plan to make security so obnoxious that everybody turns it off and leaves their machines vulnerable to attack.
I read the internet for the articles.
Many people who deal with mutliuser systems require ACLs and MACs.
Yes, but the remaining question is "why does Snowden have a slide deck on SELinux?".
Perhaps it's the *only* example he could find of NSA doing good work that did not subvert Americans' security so he took it along to demonstrate fairness.
Or perhaps not. For now I'm using selinux=0 on the kernel command line and separating concerns with virtual machines.
My God, it's Full of Source!
OUTSIDE_IP=$(dig +short my.ip @outsideip.net)
Remember the NSA has worked to HARDEN linux, and even contributed the SElinux system.
A broken clock is right twice a day.
Unless you broke it by pulling the hands off.
Confucius say, "Find worm in apple - bad. Find half a worm - worse."
I like this trick, and am glad that you're publicising it. It was a pretty clever addition to many compilers; the compilers that don't understand it won't reject the code, the compilers that do will know it's intentional. And maintenance programmers reading the code will know it's intentional, too.
(1)DOCOMEFROM!2~.2'~#1WHILE:1<-"'?.1$.2'~'"':1/.1$.2'~#0"$#65535'"$"'"'&.1$.2'~'#0$#65535'"$#0'~#32767$#1"
99.99% of programmers don't need to use single = in a conditional, so add a compiler switch to disallow it as a syntax error instead of just a warning.
In gcc, you can do -Werror=parentheses if you want to make this an error rather than a warning.
(1)DOCOMEFROM!2~.2'~#1WHILE:1<-"'?.1$.2'~'"':1/.1$.2'~#0"$#65535'"$"'"'&.1$.2'~'#0$#65535'"$#0'~#32767$#1"
no need to publicize it... just compile all your code with -Wall -Werror
Ooo, a cyber-stalker! Neat, I always wanted one of those.
Socialism: a lie told by totalitarians and believed by fools.
For some reason, I'm thinking of lightsabers.
And it's not something I do every parsec.
Confucius say, "Find worm in apple - bad. Find half a worm - worse."
I thought so too, but apparently by wrapping the statement in parenthesis "(uid=0)" the compiler warning goes away, not even -Wall -Wextra shows a warning then.
I transpose '=' for '==' not infrequently.
Mind you, its not because I'm incompetent, but because its all part of my plan to root the world.
This sig is not paradoxical or ironic.
I'm suprised that no one mentioned the Underhanded C Contest
http://underhanded.xcott.com/
Quoting their web site:
"The goal of the contest is to write code that is as readable, clear, innocent and straightforward as possible, and yet it must fail to perform at its apparent function. To be more specific, it should do something subtly evil. "
I remembered this incident when it occurred. Last month I spent an hour searching the Internet for any trace of it and came up empty. At the time I was taking an IT security course and I wanted to share the details of the incident with my classmates. Given recent events within the IT security community, this story seemed very relevant. I couldn't find anything at all so I eventually gave up.
Thank you for bringing this incident back to light.
Assuming your timing control is good. Metastable latches make your bool a p() function.
You're looking for quotes? See my journal.
In Iron sky, the Nazis obviously had no programming skills, things were hardwired:
http://felixpearce.files.wordpress.com/2012/11/richter_and_the_computer-copy_resized.jpg
Then it WAS Bush's fault!
My bad, I was just trying to contriubute to the linux code base securely.
. . . getting back at the C-language community for the lame use of "=" as an assignment operator and allowing explicit state changes (assignments -- you still have function evaluation side effect to worry about) within condition tests.
Which is handy for building a random number generator.
I should use this sig to advertise my book ISBN-13 : 978-1501515132.
The problem is not even the name of the "=" and "==" operators. The real problem is that C supports statements like a = b = c = 0, and for that requires that "=" return a value.
Rethinking email
It was you? Wasn't it?
That's why I run all my tasks as root!
Please correct the main post - you've got Ed Felten's name misspelled twice. See the cited blog post (https://freedom-to-tinker.com/blog/felten/the-linux-backdoor-attempt-of-2003/), and Wikipedia's article on him (http://en.wikipedia.org/wiki/Ed_Felten). Apparently this misspelling happens often enough that Wikipedia redirects silently.
Thanks, folks.
It was a ReplayTV DVR emulator back around 2005. I reported the issue, and it got fixed in the next release.
I thought so too, but apparently by wrapping the statement in parenthesis "(uid=0)" the compiler warning goes away, not even -Wall -Wextra shows a warning then.
First of all, uid=0 isn't a statement (uid=0; would be), but an assignment, and hence an expression. /does/ warn, if the result of such an assignment (i.e. the value the expression evaluated to) is used as a truth value (i.e. in a logical context).
gcc
This means, that
if (uid = 0) {}
will generate a warning, as intended. (Note that the assignment is still /not/ considered inside parenthesis, as the outermost parens are part of the ``if''
To silence the warning, you'd surround the assignment in parens:
if ((uid = 0)) {}
will /not/ generate a warning.
CLI paste? paste.pr0.tips!
Many people who deal with mutliuser systems require ACLs and MACs.
Yes, but the remaining question is "why does Snowden have a slide deck on SELinux?".
Perhaps it's the *only* example he could find of NSA doing good work that did not subvert Americans' security so he took it along to demonstrate fairness.
Or perhaps not. For now I'm using selinux=0 on the kernel command line and separating concerns with virtual machines.
Does having selinux=0 on the commandline mean that all selinux patches in the kernel do nothing whatsoever? Wouldn't it be better to, somehow, get a kernel with absolutely no selinux code?
In the free world the media isn't government run; the government is media run.
Yes. Government(s). That's what we're saying.
I've fallen off your lawn, and I can't get up.
It contains informative links that aren't in TFA. Well done.
Knowledge is power; knowledge shared is power lost.
Does having selinux=0 on the commandline mean that all selinux patches in the kernel do nothing whatsoever? Wouldn't it be better to, somehow, get a kernel with absolutely no selinux code?
Probably, but make sure whoever is providing that kernel for you is also providing you with security updates so you're not jumping out of the proverbial pan.
My God, it's Full of Source!
OUTSIDE_IP=$(dig +short my.ip @outsideip.net)
No, I'm going to say that the base problem is C's lack of a boolean type. Because of that, C takes anything that could reasonably be said to be equal to zero as false, and everything else as true. Given an actual boolean type, a conditional statement could require a boolean expression and flag anything else as an error. The ability to use the value of an assignment statement is occasionally convenient, but the ability to use it as a condition is a serious problem.
C's use of = and == as operators is a bit problematic, but Pascal's := is a pain. On every single computer or terminal keyboard I've used in the past forty years, either the : is shifted xor the = is shifted, which means that I have to change the shift key in the middle of an operator. It's not as annoying as some of the other things with Pascal, but it's a bit of a pain.
"When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
if ((error == ERRCODE_1 | ERRCODE_2) && (isRoot = true))
Now, what did you gain?
Rethinking email
Your kernel may not need an internal firewall. Mine certainly doesn't.
However, on a system with numerous users and various data files that only some people should have access to, it can be vital to have a reliable mechanism to run programs and handle users with minimum privileges and access. It can reduce various attack surfaces. It's fundamentally a security feature for people who need strong internal security, or who just want confidential files on a system not-entirely-trusted users are allowed onto.
"When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
*sigh*
Bill, Tonika looks interesting; not that I've looked all that much, but hadn't heard of it, so thanks for the link.
"And beyond that, the users that use Linux are likely far less interesting to the NSA...."
While Linux users are not particularly interesting to anyone (except an advertiser or demographer, e.g.), having a back door giving root would be handy should an individual end-user become a person of interest.
The attractive targets are servers, or more specifically machines used to run various networks, I should think. I doubt that a worthy enemy of the state would be conducting his core affairs on a machine connected to the 'Net; I would imagine that any machine under his control connected to the Internet would be part of the execution of some ploy and therefore backstopped and made anonymous (by cutouts and such) to a fare-thee-well.
And beyond that, the users that use Linux are likely far less interesting to the NSA than they like to tell themselves to be.
Every large financial institution in the country uses Linux on their servers.
Linux on the desktop? Mostly geeks. Linux on servers? Everywhere you look! Of course, that's also where the fun data that the NSA cares about also happens to be, on the servers...
And this comment amused me:
Linus isn't just a good C programmer. After half a decade of watching him catch stuff like this in just his public LKML messages, I'm convinced he would have seen this if he were reading braille hardcopy of it from across the room while drunk.