Good Lockdown vs. Bad
There's an ongoing series of skirmishes between corporations who want to sell products that users don't fully control and the kernel developers who want users to be the highest authority. Sometimes these skirmishes manifest in the form of security patches intended to lock down the kernel. Do they lock down the kernel against outside attackers? Or do they lock down the kernel against change from anyone at all, including the user who owns the device?
David Howells recently pushed a patch out of the linux-next, submitting it for inclusion in the main source tree. As he put it, the patch "adds kernel lockdown support for EFI secure boot". And a man page included in the patch said:
The Kernel Lockdown feature is designed to prevent both direct and indirect access to a running kernel image, attempting to protect against unauthorized modification of the kernel image and to prevent access to security and cryptographic data located in kernel memory, whilst still permitting driver modules to be loaded.
The patch gave birth to an odd debate, but a familiar one by now. Matthew Garrett, ultimately the main proponent of the patch, kept defending it on technical grounds that Linus Torvalds felt were meaningless and dishonest, hiding a secret agenda that included helping companies like Microsoft lock users out of making changes to their own systems.
Andy Lutomirski was another critic of Matthew's defense of the patch. The debate circled around and around, with Linus and Andy trying to get Matthew to admit the true motivation they believed he had and Matthew attempting to give solid reasons why the patch should go into the kernel. Things got ugly.
James Morris initially accepted the patch, planning to send it up to Linus for inclusion, and Andy reviewed the code. Among his comments, Andy said the goal of the patch was not clearly stated. He said for the purpose of his code review he would assume the goal was to prevent the root user from either reading kernel memory or intentionally corrupting the kernel.
But, he didn't think those were proper goals for a kernel, even a UEFI Secure Boot kernel. He said, "the kernel should try to get away from the idea that UEFI Secure Boot should imply annoying restrictions. It's really annoying and it's never been clear to me that it has a benefit." He singled out the idea of preventing the root user from accessing kernel memory as one of these annoying restrictions.
Kees Cook replied with his overall justification for this patch. He said:
It's about creating a bright line between uid-0 and ring-0. The most powerful of these distinctions was made long ago with signed modules. It hasn't been enough, though, since there have been many ways for uid-0 to read or write kernel memory. My expectation for this was to reasonably fill all the remaining gaps.
He also disagreed with Andy's dislike of "annoying restrictions". In fact, Kees felt that these sorts of security measures needed to be implemented even beyond UEFI Secure Boot. He said, "more than Secure Boot needs this. For example, Chrome OS's static root of trust and boot firmware isn't UEFI, but it wants this feature enabled."
But, Andy had been couching his criticism in euphemistic terms like "annoying restrictions"—his true objection was he felt the code was trying to do more than it claimed, specifically to enable companies to produce Linux devices that couldn't be modified by the user.
Andy said that even if he were willing to concede that blocking writes was a good idea for this patch, he still didn't see a value in blocking reads—particularly reads by debugging tools like kprobes and perf. He wanted to see a truly valid use case justifying the patch's features before approving it.
David offered his own justifications for the features. For one thing, he said, "to be able to pass secure boot mode over kexec, you have to make sure that the kernel image doesn't get corrupted, lest someone blacklist your signing key in the bootloader."
And in defense of restricting memory reads as well as writes, he also added, "If someone can read your kernel image, they can steal the crypto keys you use to encrypt your filesystem."
However, Andy didn't buy these justifications and seemed to feel they were just feints, trying to avoid admitting the patch's true purpose. But, he attempted to refute the arguments as stated: in terms of passing secure boot mode over kexec, he said, "I don't see what this has to do with kexec. And 'someone blacklist[ing] your key in the bootloader' sounds like a political issue, not a technical issue."
In terms of an attacker stealing the keys to read encrypted filesystems, Andy did not see an actual attack. He said:
Suppose I'm a bad guy attacking someone's laptop. If I just have normal uid != 0 access, then these patches have no effect. Instead, we're talking about an attacker who is somehow able to become global root and bypass all LSM restrictions but has not gained kernel code execution. It is indeed the case that your patches make it harder to simply read the dm-crypt encryption key out of main memory. But root can attack the disk encryption in many other ways.
He went on to list those ways:
They can persistently compromise the machine by adding services or user accounts or intentionally misconfiguring something. They can directly read the entire contents of the disk. They can modify the initrd so that the next time the machine reboots and the user types the password, the attacker gets the key (unless the TPM is involved, but getting *that* right on a standard distro is difficult or impossible). And I'm not even sure why an attacker who manages to become root wants your disk encryption key. That key is worth nothing unless the attacker makes its attack persistent, but, if the attacker can install a persistent user-level backdoor, then they can read the cleartext off your disk just as easily as they can read the ciphertext.
In a subsequent post, Andy clarified his position somewhat, perhaps trying to box his opponents into admitting their true argument. He said he wasn't opposing all concepts of "lockdown", but that he felt the current patch went beyond providing actual protections for the system. It implemented security features that he felt didn't provide actual security. Andy said that it would be good for folks to clarify exactly what kind of lockdown the patch intended, so it could be shown to be truly valuable. He remarked, "Right now there's a series of patches that check for 'lockdown' and seem to disable things that make someone uncomfortable. That's not a good way to design a security feature."
Meanwhile Matthew came into the discussion at this point, objecting to Andy's objection about an attacker blacklisting the user's key in the bootloader. Andy had described that as a political and not a technical issue, but Matthew replied, "A kernel that allows users arbitrary access to ring 0 is just an overfeatured bootloader. Why would you want secure boot in that case?"
This was the point where the true debate could be said to begin. Andy replied that the value of a secure boot without Matthew's extra lockdown code was "to get a chain of trust". He offered an example:
I can provision a system with some public keys, stored in UEFI authenticated variables, such that the system will only boot a signed image. That signed image, can, in turn, load a signed (or hashed or otherwise verified) kernel and a verified initramfs. The initramfs can run a full system from a verified (using dm-verity or similar) filesystem, for example. Now it's very hard to persistently attack this system.
Andy went on finally to voice the nature of his suspicions explicitly regarding the current patch, saying:
If I had to guess at a motivation that makes this patchset work, it would be that there is an uneasy truce between Microsoft and the various vendors of signed Linux bootloaders. That truce could conceivably require that the signed bootloaders not knowingly ship a system that allows a non-physically-present user to chainload Windows.
Chainloading is where one bootloader loads another bootloader, which then proceeds to boot the system. On dual-boot systems with Linux and Windows, for example, the GRUB bootloader typically will load the Windows boot loader in order to boot Windows.
Linus came into the discussion at this point. He replied to Matthew's statement about allowing arbitrary access to ring 0 turning the kernel into just a bloated bootloader. Linus pointed out that, "maybe you don't *want* secure boot, but it's been pushed in your face by people with an agenda?"
To which Matthew suggested that the user could just turn off the feature in that case. At that point, Linus lost his temper, perhaps tiring of the various arguments dancing around each other. He said:
So you asked a question, and then when you got an answer you said "don't do that then".
The fact is, some hardware pushes secure boot pretty hard. That has *nothing* to do with some "lockdown" mode.
Why do you conflate the two? That was the original question. You replied with another question. People answered yours.
NOW ANSWER THE ORIGINAL QUESTION, DAMMIT.
Matthew replied:
Secure Boot ensures that the firmware will only load signed bootloaders. If a signed bootloader loads a kernel that's effectively an unsigned bootloader, there's no point in using Secure Boot - you should just turn it off instead, because it's not giving you any meaningful security. Andy's example gives a scenario where by constraining your *userland* sufficiently you can get close to having the same guarantees, but that involves you having a read-only filesystem and takes you even further away from having a general purpose computer.
If you don't want Secure Boot, turn it off. If you want Secure Boot, use a kernel that behaves in a way that actually increases your security.
Al Viro felt this was avoiding the real issue. He replied:
That assumes you *can* turn that shit off. On the hardware where manufacturer has installed firmware that doesn't allow that [Secure Boot] is a misfeature that has to be worked around. Making that harder might improve the value of [Secure Boot] to said manufacturers, but what's the benefit for everybody else?
And, Linus also said bluntly to Matthew:
Bullshit.
I may want to know that I'm running *my* kernel, but once that is the case, I trust it.
In fact, I tend to trust it more than some random vendor key. You should too.
Your whole argument is FUNDAMENTALLY garbage. It's the Disney kind of garbage. It was garbage back then, and it's garbage now.
It is also garbage for a simple technical reason: secure boot can be hard to turn off. Sometimes "turn off" means "you just have to add your own keys".
Yes, on x86 hardware at least at some point MS actually had the rule that it has to be something you can turn off. That rule is apparently not true on ARM, though.
Seriously. You sound like you're parroting some party line, not like you are answering the actual question.
So again: why do you conflate the two issues?
If you want lockdown, fine, enable it. But what the F*CK does that have to do with whether you had secure boot or not?
Matthew continued to restate his position, saying:
If you don't believe that your self-signed kernel is going to be a threat against your security model then great! Don't turn this on when you build it. But if you built a kernel that didn't have this lockdown functionality and got it signed with, say, Red Hat's signing keys, anyone could take Red Hat's bootloader chain and that kernel and subvert the Secure Boot chain on any machine that trusts the third party signing key (ie, basically all of them).
And regarding MS not having the rule on ARM that Secure Boot had to have an "off" switch, Matthew replied, "Correct - there's no requirement that it be something you can disable on ARM, but since Microsoft won't sign any third-party code for ARM anyway it makes no difference to this discussion."
At around this point in the discussion, James (who originally had accepted the patch and had planned to push it up to Linus) said that based on this debate, he was withdrawing his approval and would not push the code up to Linus after all.
But the discussion continued, with neither side making headway against the other. At one point, Linus took the tack that lockdown would make the kernel harder to debug. He said:
I do not want my kernel to act differently depending on some really esoteric detail in how it was booted. That is fundamentally wrong.
Is that really so hard to understand?
Look at it this way: maybe lockdown breaks some application because that app does something odd. I get a report of that happening, and it so happens that the reporter is running the same distro I am, so I try it with his exact kernel configuration, and it works for me.
It is *entirely* non-obvious that the reporter happened to run a distro kernel that had secure boot enabled, and I obviously do not.
See what the problem is? Tying these things magically together IS A BAD IDEA.
And when people ask you why you did it, YOU HAVE YET TO COME UP WITH A SINGLE ACTUAL RESPONSE.
Instead, you just ask people why they care, or tell people to not enable it.
Seriously, Matthew, it's WRONG to tie things together in magic ways when they have nothing what-so-ever to do with each other.
So no. The answer is simply "don't tie the two things together".
And dammit, if you tie them together, you had damn well have a good reason. So far, your reasons have _literally_ been "Why not?" and tried to make the onus be on others to explain to you why not.
That's not the right approach to begin with, Matthew. The onus is on *you* to explain why you tied them together, not on others to explain to you - over and over - that they have nothing to do with each other.
This discussion is over until you give an actual honest-to-goodness reason for why you tied the two features together. No more "Why not?" crap.
In his next post, Linus added, "Side note: I suspect the reason is something along the lines of 'there are political reasons'. But dammit, if that's the case, those should be documented and explained, not answered with 'why not' when people ask why something is the case."
Matthew offered another explanation of his position:
1) Secure Boot is intended to permit the construction of a boot chain that only runs ring 0 code that the user considers trustworthy.
2) Allowing arbitrary user code to run in ring 0 without affirmative consent on the part of the user is therefore incompatible with the goals of Secure Boot.
3) This patchset provides a mechanism to alter the behaviour of the kernel such that it is significantly more difficult for arbitrary user code to run in ring 0 without affirmative user consent.
4) Providing a mechanism for automatically enabling this behaviour when running in a context that is intended to restrict access to ring 0 is a rational thing to do, because otherwise it is difficult to achieve the objective in (1).
Alternative approaches to achieve (1) rely on severely constraining userland - ChromeOS, for instance, doesn't impose these restrictions at present but also doesn't allow users to run arbitrary applications (you're stuck inside either the Chrome or Android sandbox). So, if the goal is to achieve (1) when the platform is in this state, what's a more reasonable alternative?
Linus replied point-by-point.
To Matthew's point #1, Linus said this was not necessarily the intention of Secure Boot. He said, "That may be *one* intention, for some people. It's not an a-priori one for the actual user."
To point #2, Linus said, "Those goals are not the *user's* goals. Be honest now. It wasn't generally users who clamored for it. If the user actually wanted it, and is asking for it, he can enable it. Independently of secure boot, which the user generally has little control over."
To point #3, Linus said the protection Matthew described already existed, in restricting kernels to load modules only by the root user, or to load only signed modules. The difference being that "they don't magically enable themselves (or disable themselves) depending on whether you booted with secure boot or not."
And to point #4, Linus replied:
No. See why it's *NOT* rational, as explained already several times.
Magically changing kernel behavior depending on some subtle and often unintentional bootup behavior detail is completely idiotic.
It would be idiotic if it was that "check kernel module signatures" check. This is no less idiotic.
Seriously, listen to your own arguments. If they don't make sense for checking kernel module signatures, why the hell would they make sense for something like lockdown.
THE TWO THINGS ARE ENTIRELY INDEPENDENT.
I'm done with you. You're not listening, and you're repeating bogus arguments that make no sense.
No way in hell will I merge anything like this.
And eventually, Linus said:
Matthew, it's simply not worth continuing talking with you.
I'll just not pull this crap, and vendors that you convince to do stupid things have only themselves to blame.
You clearly have an agenda, and are not willing to look at arguments against your idiotic choices.
In spite of this, Linus did continue the debate with Matthew, at one point also saying, "you're pushing this whole 'not secure boot' means 'trivial circumvention' much much too hard. To the point of it being an outright lie."
Eventually over the course of discussion, Linus gave his estimate of what Matthew's real argument was. He said:
I find it a *lot* more convincing to hear "We'd like to just enable it all the time, but it's known to break some unusual hardware cases that we can't fix in software, and we wanted *some* way to disable it that requires explicit and verified user intervention to do that, and disabling secure boot is the easiest hack we could come up with."
See? No bullshit. Just straight talk about the *actual* reason why people decided on this particular tie-in, and admitting that it's a hack, but also clearly stating the reason for the hack.
Now, I still don't necessarily agree that it's the best possible option, but when stated in those terms I at least understand why that option was picked as a reasonable one, and it changes the discussion a lot, and (at least for me) makes it much more palatable.
Because as long as the explanation is just some "you must use secure boot or you've already lost and further security is pointless" hocus-pocus magical thinking, I immediately go "no, that sounds completely bogus, and it makes testing and coverage much worse, we've done other things quite like that without this secure boot tie-in."
This type of discussion is unusual for kernel development, but not for this particular type of patch. The attempts to slip code into the kernel that will enable a vendor to lock users out of controlling their own systems always tend to involve the two sides completely talking past each other. Linus and Andy were unable to get Matthew to address the issue the way they wanted, and Matthew was unable to convince Linus and Andy that his technical explanations were genuine and legitimate. Meanwhile, people like Kees probably have legitimate reasons for supporting the patch, but simply have philosophical differences with Linus about what constitutes true security. So, they end up arguing alongside Matthew, although for different reasons.
One fascinating element that I didn't quite capture in this summary was the way Linus continued to address Matthew's technical points, long after the moment when he had already stated that he felt Matthew's argument to be disingenuous and even an outright lie, and that he would never accept the submitted patch. Why did he continue the debate, even while holding such a negative view of it? It's possible that Linus was searching for a "perfect argument"—a technical explanation so obviously correct that even Matthew would have to drop all pretense and admit that his position was wrong. Or it's possible that neither Linus nor Matthew was speaking to each other and each had a wider audience in view. Perhaps Matthew was speaking truly to his employers, showing that he would tow the line. Perhaps Linus also was speaking truly to Matthew's employer, and to others like them, showing that he saw through their efforts and would not be fooled.
Or maybe I'm too quick to believe Linus and Andy's accusations, and in reality, Matthew was simply proposing a security enhancement he genuinely believed would help the user.
Note: if you're mentioned above and want to post a response above the comment section, send a message with your response text to ljeditor@linuxjournal.com.