[personal profile] mjg59
David Howells recently published the latest version of his kernel lockdown patchset. This is intended to strengthen the boundary between root and the kernel by imposing additional restrictions that prevent root from modifying the kernel at runtime. It's not the first feature of this sort - /dev/mem no longer allows you to overwrite arbitrary kernel memory, and you can configure the kernel so only signed modules can be loaded. But the present state of things is that these security features can be easily circumvented (by using kexec to modify the kernel security policy, for instance).

Why do you want lockdown? If you've got a setup where you know that your system is booting a trustworthy kernel (you're running a system that does cryptographic verification of its boot chain, or you built and installed the kernel yourself, for instance) then you can trust the kernel to keep secrets safe from even root. But if root is able to modify the running kernel, that guarantee goes away. As a result, it makes sense to extend the security policy from the boot environment up to the running kernel - it's really just an extension of configuring the kernel to require signed modules.

The patchset itself isn't hugely conceptually controversial, although there's disagreement over the precise form of certain restrictions. But one patch has, because it associates whether or not lockdown is enabled with whether or not UEFI Secure Boot is enabled. There's some backstory that's important here.

Most kernel features get turned on or off by either build-time configuration or by passing arguments to the kernel at boot time. There's two ways that this patchset allows a bootloader to tell the kernel to enable lockdown mode - it can either pass the lockdown argument on the kernel command line, or it can set the secure_boot flag in the bootparams structure that's passed to the kernel. If you're running in an environment where you're able to verify the kernel before booting it (either through cryptographic validation of the kernel, or knowing that there's a secret tied to the TPM that will prevent the system booting if the kernel's been tampered with), you can turn on lockdown.

There's a catch on UEFI systems, though - you can build the kernel so that it looks like an EFI executable, and then run it directly from the firmware. The firmware doesn't know about Linux, so can't populate the bootparam structure, and there's no mechanism to enforce command lines so we can't rely on that either. The controversial patch simply adds a kernel configuration option that automatically enables lockdown when UEFI secure boot is enabled and otherwise leaves it up to the user to choose whether or not to turn it on.

Why do we want lockdown enabled when booting via UEFI secure boot? UEFI secure boot is designed to prevent the booting of any bootloaders that the owner of the system doesn't consider trustworthy[1]. But a bootloader is only software - the only thing that distinguishes it from, say, Firefox is that Firefox is running in user mode and has no direct access to the hardware. The kernel does have direct access to the hardware, and so there's no meaningful distinction between what grub can do and what the kernel can do. If you can run arbitrary code in the kernel then you can use the kernel to boot anything you want, which defeats the point of UEFI Secure Boot. Linux distributions don't want their kernels to be used to be used as part of an attack chain against other distributions or operating systems, so they enable lockdown (or equivalent functionality) for kernels booted this way.

So why not enable it everywhere? There's a couple of reasons. The first is that some of the features may break things people need - for instance, some strange embedded apps communicate with PCI devices by mmap()ing resources directly from sysfs[2]. This is blocked by lockdown, which would break them. Distributions would then have to ship an additional kernel that had lockdown disabled (it's not possible to just have a command line argument that disables it, because an attacker could simply pass that), and users would have to disable secure boot to boot that anyway. It's easier to just tie the two together.

The second is that it presents a promise of security that isn't really there if your system didn't verify the kernel. If an attacker can replace your bootloader or kernel then the ability to modify your kernel at runtime is less interesting - they can just wait for the next reboot. Appearing to give users safety assurances that are much less strong than they seem to be isn't good for keeping users safe.

So, what about people whose work is impacted by lockdown? Right now there's two ways to get stuff blocked by lockdown unblocked: either disable secure boot[3] (which will disable it until you enable secure boot again) or press alt-sysrq-x (which will disable it until the next boot). Discussion has suggested that having an additional secure variable that disables lockdown without disabling secure boot validation might be helpful, and it's not difficult to implement that so it'll probably happen.

Overall: the patchset isn't controversial, just the way it's integrated with UEFI secure boot. The reason it's integrated with UEFI secure boot is because that's the policy most distributions want, since the alternative is to enable it everywhere even when it doesn't provide real benefits but does provide additional support overhead. You can use it even if you're not using UEFI secure boot. We should have just called it securelevel.

[1] Of course, if the owner of a system isn't allowed to make that determination themselves, the same technology is restricting the freedom of the user. This is abhorrent, and sadly it's the default situation in many devices outside the PC ecosystem - most of them not using UEFI. But almost any security solution that aims to prevent malicious software from running can also be used to prevent any software from running, and the problem here is the people unwilling to provide that policy to users rather than the security features.
[2] This is how X.org used to work until the advent of kernel modesetting
[3] If your vendor doesn't provide a firmware option for this, run sudo mokutil --disable-validation

User vs Distribution

Date: 2018-04-08 01:23 am (UTC)
From: (Anonymous)
So, one of your arguments from this post is that there is no way to enforce the kernel cmdline if booted as an EFI executable, but I am doing exactly that since quite some time: I roll the kernel, initrd and cmdline into one EFI binary and then sign that.
AFAIK this prevents anyone from changing the cmdline (please correct me if I am wrong). I think I even learned about this possibility from this very blog :)

However, I think I realize why this "doesn't count" for your argumentation: It would be highly impractical for a distribution to ship this signed blob, as the initrd is usually generated on the users system and the cmdline might also need to account for the users individual setup (root partition or mount arguments at least).
So from a Distributions perspective I want lockdown linked to UEFI because then I can sign this lockdown-enabled kernel, ship it, and guarantee to every user that - if secure boot is on and my keys are enrolled in the firmware - whatever kernel or OS may have been booted or chainloded into, it was signed by me and hadn't be tampered with.

I already see a problem with this: How can the user check if secure boot is actually enabled? If someone managed to compromise the system and turn secure boot off (for example by using shim), they could just boot a system that makes it look like secure boot is enabled.
But this is not my main problem with the patch:

Currently, I am using my distributions prebuilt kernel, as I've had no need for custom kernel options since a long time. I also use secure boot to verify my kernel+initrd+cmdline, as mentioned earlier. I don't really trust the proprietary implementation of it, but it's better than not using secure boot. Everything besides the UEFI boot partition is encrypted, so I "use" this encryption to further verify my boot chain. I know that it's theoretically possible to tamper with an encrypted disk without knowing the encryption key, but again better than nothing.
So I really don't want to disable secure boot, but I might want to disable lockdown (and I can imagine that there are more people who want that than just me). Maybe I want to chainload into something unsigned, but I (sufficiently) trust it because it comes from my encrypted disks.
But if my distribution enables the lockdown option as is, I would have to build my own kernel from now on, until possibly forever. I might even have to maintain my own patch set if I want to leave lockdown available as a cmdline option, but not tie it to secure boot!
That, or the distribution still would have to ship two kernels: One with lockdown tied to secure boot, signed; one with lockdown not tied to secure boot, unsigned.

So, this might actually be a user vs distribution thing. The user wants to disable lockdown without disabling secure boot, but the distribution wants to be able to give guarantees to other users (or maybe other software vendors).

As a user, I don't want to accept the lockdown patches as is. But I think there is another way to solve this, which might be acceptable to Distributions: The distribution ships a tiny signed bootloader that enforces the lockdown argument on the cmdline. The kernel is then signed in a different way, so it can't be booted directly with secure boot but only via the bootloader. There is still an amount of work needed for this (mainly signing the kernel in this "different way"), but it probably beats shipping two kernels, one with a possibly out-of-tree version of lockdown. And I would definitely prefer this over rolling my own kernel from now ;)

Another tiny thing: If the current lockdown patches allow for lockdown to be disabled with alt-sysrq-x during runtime, wouldn't this invalidate all the efforts of lockdown? Say I boot a signed Fedora, disable lockdown, then somehow chainload into a modified Windows which sees secure boot is still active?

Profile

Matthew Garrett

About Matthew

Power management, mobile and firmware developer on Linux. Security developer at Google. Ex-biologist. @mjg59 on Twitter. Content here should not be interpreted as the opinion of my employer.

Page Summary

Expand Cut Tags

No cut tags