Signed kernel can load unprotected initrd #65
Labels
No labels
bug
dependency
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
review-next
security
stub
tool
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: raito/lanzaboote#65
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
As far as I understand, lanzaboote aims to protect the known kernel+initrd combinations using a signature on the stub UKI containing their hashes.
However, it also signs the kernel (presumably so that LoadImage works). Thus, it is possible to instruct systemd-boot to boot a Linux kernel directly, pointing it to an unprotected initrd.
AFAIK, the stub UKI contains also the command line, the only way I see to load an unprotected initrd is to have:
trick systemd-boot into loading signed kernel with custom command line to load this particular unprotected initrd directly right?
If systemd-boot prevented loading anything else beyond a UKI, would that close this vulnerability to your opinion?
Yes, this is exactly what I mean. The kernel is signed, so systemd-boot will happily boot it (with arbitrary cmdline) if instructed to do so via a boot loader entry, and the kernel will in turn load the unsigned initrd because it doesn't even try to verify initrds to begin with.
I believe so.
Okay, going through literature and what systemd has done with UKIs & all, I think this is out of scope for pure SecureBoot protections.
The only way to protect against such threats with SecureBoot only is to use a proper UKI (with the kernel baked in at least) and don't sign non-UKI images, for now, we do not offer such things with lanzaboote at the moment.
Producing UKI though is really easy and has been done as part of https://github.com/DeterminateSystems/bootspec-secureboot that we should maybe salvage to offer this possibility.
Unfortunately, such a mechanism will require "large" ESP or accept to have few generations.
In fact, this might not be a useful thing to pursue because it reduces the problem to find a signed bootloader with custom command line edit allowed when they are not baked in.
Thus, I think this thing should be resolved using a trusted boot mechanism, so relying on TPM2 to prevent decryption of the disk and having the adequate PCRs, etc.
We would basically have to make sure that we sign nothing that allows loading a kernel with arbitrary initrd or cmdline in the end. I see multiple possibilities for this:
This reduction is only simple if Microsoft keys are enrolled. Even there, as more of the ecosystem is moving towards UKI, I expect Microsoft to dbx such bootloaders some day (it's likely going to take a few more years, though).
I'm not really familiar with trusted boot, but as far as I understand, implementing that would require verification of the TMP2 measurements by trusted software. In the present case, I believe this would amount to the kernel doing the verification before it loads any modules (since those come from the untrusted initrd). At this point, you can probably just as well patch the kernel to refuse booting with unsigned initrd and cmdline.
This seems like a pretty practical solution. We might be able to leverage some other entry points of the kernel (PVH or the normal bzImage entry point)
It seems
systemd-boot
can load unsigned kernel images embedded in UKI by installing a security override.https://github.com/systemd/systemd/blob/v253-rc1/src/boot/efi/linux.c#L71
https://github.com/systemd/systemd/blob/v253-rc1/src/boot/efi/secure-boot.c#L175
That's an interesting alternative. I will check that out.
That's an interesting alternative. I will check that out.