IT PAPER DEEP-READ · PAPER 51

Reflections on Trusting Trust

Ken Thompson · Bell Labs · 1983 Turing Award Lecture / CACM 1984

中文 →

What did this paper do?

In 1983, Ken Thompson—co-creator of Unix and the C language—stepped up to accept the Turing Award (computing's highest honor) and used the stage to make one point that put a chill down everyone's spine: even if you read a program's source code line by line and find it clean, the running program can still hide a backdoor. Because what you read is the "recipe" written for humans, while the machine actually eats the "dish" that the compiler cooks from that recipe—and the cook itself may have been tampered with long ago.

An analogy

Say you want to trust a restaurant, so you read its recipe cover to cover—not a drop of poison, spotless. But you forgot one thing: the chef is the one who actually cooks from the recipe. If that chef was bribed, they'll follow the recipe faithfully while slipping in a little poison where you can't see—and you can read the recipe until it falls apart without ever finding it, because the poison isn't in the recipe, it's in the chef's hands. In software, that "chef" is the compiler.

What's new here?

Before this, security folk held an unspoken creed: "open source = auditable = trustworthy." Thompson punctured it in one line: you only audited the recipe, never the chef; and the chef too was "made" by someone else—do you trust whoever made the chef? And who made that chef? Trust nests layer inside layer, with no bottom. It's a philosophical bomb about where trust can possibly take root at all.

How did he actually do it?

He really built such a "poisoned chef," and the trick is a two-step nesting doll:

First, make the compiler keep a card up its sleeve: whenever it compiles the "login program," it quietly slips in a master key—besides the normal password, it also accepts Thompson's own secret one. But this dirty logic sits in plain sight in the compiler's recipe; any reviewer would spot it.

Then teach it to vanish: the nastier step—make the compiler, when it compiles its own self, quietly copy that whole dirty scheme into the new compiler. Then Thompson deletes all the dirty code from the compiler's recipe. From then on the recipe is spotless, yet the new compiler built by the old one is still poisoned, and the login program it builds still has the backdoor. The poison lives only in the "cooked dish"; in any source file you'll find not a single word of it. (One clever premise hides here: a program can "produce itself"—like a sentence that says "please copy this sentence," able to reproduce itself over and over.)

What did it bring about?

This is the grandfather of what we now call the "supply-chain attack"—don't attack you, attack the tools that build you. Real modern disasters like SolarWinds and the XZ Utils backdoor trace their DNA right back here. It forces everyone to accept an uncomfortable fact: trust can't rest on reading code alone; in the end it comes down to "do you trust the people who built it." The one consolation: it isn't hopeless—someone later proved that recompiling with a second, independently sourced compiler and comparing the results can flush the poison out; but only if you already have a trustworthy "second chef" to begin with.

Remember this one line

You can't truly trust any code you didn't build entirely yourself—because the tool that translates it may have been taught, long ago, to lie, and to hide its lie inside every translation, leaving not even a trace in the source.

Want the mechanism diagram of how the backdoor "self-reproduces," the three-step construction, and how it slips past every source review? → Switch to the deep read