Secure bootstrapping (by alaric)
Back in the day, Ken Thompson described a rather scary problem with the way programming languages are compiled.
In summary, one could modify the C compiler so that, when it compiled some security-critical application like sshd
, it inserted a security hole. The pristine sshd sources, when compiled, would produce a vulnerable executable. But then to protect the modification to the C compiler from being found, one can use the same trick on the compiler - make it insert the bugs into sshd and into itself when compiled from pristine sources. Compile this compiler up, then test it on its original sources, and when it's all working OK, install it on a system (and the bad sshd) and remove the dodgy sources. Clear your .bash_history
and you're done 😉
The thing is, this bug could then lurk in the system for decades. Until the source code for sshd
or the C compiler itself changes sufficiently for the 'patch' built into the C compiler to stop working, the bug will propogate every time the C compiler is recompiled. Even for other architectures and operating systems. If something like this was done to gcc
, then just about every Unix system out there would be vulnerable. Certainly all the open source ones, and MacOS X.
The problem is that spotting the bug would require manual examination of the binaries. And not with a disassembler compiled with gcc
, either - as Ken suggested, you can also make the compiler patch the disassembler to make it hide the work done by the compiler patch.
I wonder if the computers I'm using to write this have backdoors snuck in that way. I wonder if the computer you're using to read it has any. A well-funded adversary could go to great lengths to comprehensively much up gcc
, with intelligent pattern matching in the patch so that it will survive a fair amount of source code drift in the compiler before breaking, and cunningly spreading the effect of it over various wide-spread bits of code, so the overall effect isn't easily visible to somebody grovelling through the resulting machine code. GCHQ or the NSA, perhaps.
This is a contributing factor towards my desire to not base ARGON on top of gcc
. I'm designing HYDROGEN so that it can be implemented in machine code (can you even trust an assembler?) if necessary, and CHROME is to be implemented in HYDROGEN rather than in itself (metaprogramming doesn't count, since the results of the metaprograms aren't fed back into the same metaprograms).
There's still scope for vulnerabilities to be snuck in at the BIOS level, or with something in your bootstrap chain, but they can't self-propogate!
By Ben, Mon 16th Apr 2007 @ 2:16 pm
How do you know someone hasn't patched the microcode in your CPU?
By alaric, Mon 16th Apr 2007 @ 2:26 pm
You don't. But that's not a bug that can self replicate (unless you managed to make the CPU notice when it's running a chip design app... but that's tricky!).
If somebody gets to your hardware (be it during manufacture or when you have it), then you're stuffed anyway. PCI bus loggers. Dodgy CPUs. A funny BIOS. Heck, even DIMMs with a little processor inside that patches the OS in-memory.
But all of these are expensive hacks, relatively. Even if somebody like GCHQ went sneaking loopholes into the designs for, say, Ethernet controllers (so it's easy for them to send in a probe packet that makes the Ethernet controller master the PCI bus and read/write arbitrary memory addresses on demand), there's a lot of different makes for them to worry about, and new ones coming out all the time, so it's possibly not worth their while.
But a self-replicating gcc hole would probably be a good cost/benefit tradeoff for them!
By Ben, Mon 16th Apr 2007 @ 2:43 pm
Actually I think this is a Solved Problem(tm):
http://www.schneier.com/blog/archives/2006/01/countering_trus.html
By alaric, Mon 16th Apr 2007 @ 3:14 pm
That's a clever way to detect the problem!
The 'compiler' should be considered to include the OS and everything above it, of course, since an exploit could be hidden in the kernel, in libc, ...
So has anyone actually tried this test? 😀