-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Removal of SD_TPM_PCR option breaks grub + sd-stub set-ups #22635
Comments
@xnox ^^ |
I don't quite see why grub/sd-boot/sd-stub should be using different PCRs to measure the same thing. That's literally what a PCR measurement is supposed to be for, no? /cc @poettering |
I am not sure I follow? Using the kernel cmdline PCR to distinguish boot loaders sounds quite a surprising use for them? Can you elaborate? Why not just check for contents of |
Backport patches for systemd stub from systemd v250. These patches add support to arm64 kernels by using a new kernel feature [1] for passing the address of the initramfs to the kernel stub by a special device path using the LoadFile2 EFI protocol. This feature is now used also for x86. Support is in kernel 5.7 for arm64 and in 5.8 for x86. The patches included are those affecting the src/boot/efi/ folder up to commit [2]. Note that we are patching the Ubuntu package, which uses as base https://github.com/systemd/systemd-stable/releases/tag/v249.10 , so some patches from v250 are already backported there. Additionally, [3] from post-v250 has been included as well. When backporting the patches, [4] has not been included because we need to set a PCR different to the one in grub for measuring kernel command line. An issue for this problem [5] has been opened in systemd upstream. Also, [6] was not included either because it touched many paths outside src/boot/efi/ and it is a cosmetic change. Finally, some commits that do not touch src/boot/efi/ were also included as they were needed because they do some refactoring of macros that affect the sd-stub code. These are: 0003-alloc-util-make-mfree-typesafe.patch 5afcf89ca29b518eb2fa244b015afc2708f77e1d 0004-macro-Move-some-macros-to-macro-fundamental.h.patch f862e847246b5588d9d6ed7d91da11b6adbf39e7 0069-fundamental-define-size_t-and-memcpy-for-sd-boot.patch 5d8a725b0800ce572bb3308c03e98561251a9284 0071-move-mfree-to-macro-fundamentals.h.patch 200b1d997d96179aba9489ce9d373e869557460e [1] torvalds/linux@ec93fc3 [2] systemd/systemd@33bc9b7 [3] systemd/systemd@178d598 [4] systemd/systemd@faacf18 [5] systemd/systemd#22635 [6] systemd/systemd@fce9abb
Dropping from milestone, I don#t think it's obvious what the right approach here is, I simply understand the rationale here. |
Backport patches for systemd stub from systemd v250. These patches add support to arm64 kernels by using a new kernel feature [1] for passing the address of the initramfs to the kernel stub by a special device path using the LoadFile2 EFI protocol. This feature is now used also for x86. Support is in kernel 5.7 for arm64 and in 5.8 for x86. The patches included are those affecting the src/boot/efi/ folder up to commit [2]. Note that we are patching the Ubuntu package, which uses as base https://github.com/systemd/systemd-stable/releases/tag/v249.10 , so some patches from v250 are already backported there. Additionally, [3] from post-v250 has been included as well. When backporting the patches, [4] has not been included because we need to set a PCR different to the one in grub for measuring kernel command line. An issue for this problem [5] has been opened in systemd upstream. Also, [6] was not included either because it touched many paths outside src/boot/efi/ and it is a cosmetic change. Finally, some commits that do not touch src/boot/efi/ were also included as they were needed because they do some refactoring of macros that affect the sd-stub code. These are: 0003-alloc-util-make-mfree-typesafe.patch 5afcf89ca29b518eb2fa244b015afc2708f77e1d 0004-macro-Move-some-macros-to-macro-fundamental.h.patch f862e847246b5588d9d6ed7d91da11b6adbf39e7 0069-fundamental-define-size_t-and-memcpy-for-sd-boot.patch 5d8a725b0800ce572bb3308c03e98561251a9284 0071-move-mfree-to-macro-fundamentals.h.patch 200b1d997d96179aba9489ce9d373e869557460e [1] torvalds/linux@ec93fc3 [2] systemd/systemd@33bc9b7 [3] systemd/systemd@178d598 [4] systemd/systemd@faacf18 [5] systemd/systemd#22635 [6] systemd/systemd@fce9abb
I will provide bios measurements log to explain what is going on. |
tl;dr it is impossible to compute PCR values when grub chainloads systemd-boot or Boot Loader Specification type 2 binary, because grub measures a lot of things into PCR 8.
On Ubuntu Core we boot into shim (because we must boot shim to support Secureboot on systems with MS certificates). And here lies the problem. For example offline addition of recovery systems, which one doesn't seal secret against, invalidate the valid boot entry to boot the encrypted system, because grub measures extra commands into PCR8 because it parsed them even when user didn't pick to boot them. Using the https://github.com/canonical/tcglog-parser/tree/master/tcglog-dump you can see that by default grub measures every step of its execution into PCR 8 making a complete mess of it. Furthermore, the way it does measurements are hardware dependend i.e. $prefix can be different, and are not exactly round-trip safe (for example there is a lot of whitespace mangling and quoting issues). There is no grub.cfg tpm measurements simulator either that can be used to predict a finite set of measurements for the kernel commandline that one wants to seal against. Thus instead of trying to predict the final states of the grub's PCR 8 that is in the below form of to seal against cmdline args
We instead configure systemd-boot to measure to PCR 12 (currently universally unused). Which results in a clean measurement of the commandline that is passed to the kernel image i.e.
Which is hardware independent, and easy to parse and predict. For example we allow a few PCR12 values those that match a few different allowed To continue using BLS type 2 binaries that are chainloader loaded by grub, with predictable PCR measurements, it would be nice if systemd-boot would switch by default to a clean PCR 12 (i.e. explicitly different PCR from grub's one), or for it to keep the PCR measurement number build time configurable to allow distributions to sefl-allocate different PCRs to different bootloaders, and thus allowing easy ways to precompute policies when multiple bootloaders are used during boot. I.e. on Ubuntu so far we have been using PCR 8 for grub mess, PCR 12 for clean declarative systemd-boot measurements across our Desktop, Server and IoT product lines. |
From shim-review: Ultimately, this looks to me like grub and sd-boot (mayber others?) aren't on an agreement/standard as to what to measure into what. In particular, the PCR8 measurement doesn't look very useful to me for a "it's the kernel command line" when it puts everything and the kitchen sink in it (which can easily change on boot loader upgrades)… |
sd-boot has not had security review and at the moment the bootloader efi app is not signed by any of the linux distros (including the major ones like debian/fedora/ubuntu/rhel/suse/oracle/etc.). I think it is out of scope to discuss this. As far as i can tell the only apps that are signed are shim, shim-fallback, shim-mokmanager, grub in various configurations, fwupd firmware updater, and linux kernels with various EFI entry point stubs (i.e. sd-boot stub and/or kernel efi stub).
Whilst that is true, and a good goal, it is currently the state of affairs that grub imho over-measures a lot. and as a distribution i have no option to backwards compat support that grub behaviour, whilst still trying to land new OS features that use sd-boot stub. But also note that measuring pcr8 was a way to detect and protect oneself from grub acpi-bypass vulnerability, precisely because grub measures everything it does via all of its commands. Given that grub's complexity which looks like a turing complete mini-OS, I am not sure they would be open to measuring less things. It is also not nice for the systemd-boot project to remove a feature that is actively used for 3 years and shipped in production by one vendor, with what I hope I demonstrated as a valid use case whilst being stuck between a rock and a hard place. I'm not too sure what I can propose to be universal going forward. I.e. PCR#8 at this point looks like a bootloader-specific freeform whatever. And I kind of want / need to define a PCR#12 to be "the args/cmdline passed to StartImage of an EFI app binary that happens to be a linux kernel" which is also a very tough sell, as it is very EFI & OS specific. Given that many other architectures use TPM measurements without any args, or not using EFI at all. Please resurrect compile time configuration of where sd-boot sends TPM measurements, as removal of this features breaks backwards compat in production systems. |
yikes, those measurements grub is doing there are some serious garbage. I'd really be interested in removing any variables of PCR assignment from the game in the long run, i.e. the others typically hard code the PCR numbers, and so should we. i.e. I'd like to have reasonably universially adopted PCR meanings if possible. If grub does such a mess with PCR 8, maybe we should switch to PCR 12 altogether for our measurements? and leave PCR 8 in the mess it is? I wonder what a good approach could be there. Just hard switch our stuff to PCR 12? or switch to PCR 12, but optionally additionally measure into PCR 8 as compat ifdeffery? |
I am leaning towards this approach. i.e. hardcode PCR 12 now in our codebase, document it in our man pages. Then, add a boolean compat knob in meson that if enabled also enables PCR 8 measurement, but now defaults to off, plus a NEWS story that hints we'll drop that in 1 year or two and people should migrate to PCR 12. |
Would be happy to review a patch along those lines. i.e. not reintroduce the old configurability of the PCR to use, but just a build-time to choose between "only new-style" or "new-style + old-style simultaneously". |
Yeap, squatting a PCR # seems to be the way to go here. And I like your proposed strategy here. |
Just a headsup that Bitlocker reserves the use of PCR12 for "Data events and highly volatile events". I'm not sure what that means or if it's relevant if someone winds up dual-booting Linux and Windows with bitlocker? https://github.com/tianocore-docs/edk2-TrustedBootChain/blob/main/4_Other_Trusted_Boot_Chains.md |
reading that, it sounds like it should be ok. Because we don't want to boot windows bootmgr from systemd-boot probably, instead we'd want people to use direct UEFI windows boot entry instead. Thus systemd-boot is not a boot sequence to affect windows boot sequence PCR measurements. |
But maybe we should add ourselves to that table. It looks nice. |
Not sure how well maintained it is. Been trying to keep the archwiki updated on my end. |
Dropping from the milestone for now. Let's not delay the release for this. I think there's sufficient consensus on how to fix this properly, just somebody needs to prep the patch for it. If none is supplied by release time I think while this is technically a regression it's trivial to work around in Ubuntu's private builds, so not sure it's worth delaying the release for. |
Apparently Grub is measure all kinds of garbage into PCR 8. Since people apparently chainload sd-boot from grub, let's thus stay away from 8, and use PCR 12 instead for the kernel command line. As discussed here: systemd#22635 Fixes: systemd#22635
Ah, well, to make it easy I prepped PR #22761. |
Apparently Grub is measuring all kinds of garbage into PCR 8. Since people apparently chainload sd-boot from grub, let's thus stay away from PCR 8, and use PCR 12 instead for the kernel command line. As discussed here: systemd#22635 Fixes: systemd#22635
Support for this was dropped in faacf18. However, following discussion in [1], upstream changed the hardcoded PCR index for kernel command line measurement from 8 to 12 in 4d32507. Thus, there is no functional change here. [1] systemd#22635
systemd version the issue has been seen with
v250
Used distribution
Ubuntu
Linux kernel version used (
uname -a
)Linux host 5.4.0-100-generic #113-Ubuntu SMP Thu Feb 3 18:43:29 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
CPU architecture issue was seen on
x86
Expected behaviour you didn't see
NA
Unexpected behaviour you saw
Commit faacf18 breaks Ubuntu setups. In Ubuntu, we configure grub with PCR8 whilst we configure sd-stub with PCR12. This allows us to seal, compute, and differentiate cmdlines as measured by grub and as measured by sd-stub, on the same system.
Could the commit be reverted please?
Or for example use distinct from grub pcr by default, i.e. 12 - which i guess will not fly, given it is a breaking change for anybody who only ever used sdstub only without grub.
Simultaneous measurements of cmdline to the same pcr by either grub & sd-stub and harder to compute sealing policies for if one wants to support one/another/either.
Steps to reproduce the problem
NA
Additional program output to the terminal or log subsystem illustrating the issue
NA
The text was updated successfully, but these errors were encountered: