Support shim protocol in EFI unified kernel image stub
Component
systemd-stub
Is your feature request related to a problem? Please describe
EFI unified kernel image fails to boot when:
- Secure Boot is enabled
- shim 15.3 or newer is used to load EFI unified kernel image
- EFI unified kernel image is signed with enrolled MOK key
The failure message is:
Bootloader has not verified loaded image. System is compromised. halting.
shim does not consider systemd stub as a participating loader because systemd stub does not call shim verify function.
Describe the solution you'd like
Check if shim protocol is loaded and call shim_verify() on any (potentially dummy) data. For the time being shim_verify() return code does not matter, i.e. as long as shim_verify() is called with any non-negative size shim will consider the loader to be participating.
Describe alternatives you've considered
Alternative is to either use full fledged bootloader (e.g. systemd-boot) that does load kernel and initrd from filesystem (and verifies loaded files using shim) or to disable shim validation with mokutil --disable-validation.
The systemd version you checked that didn't have the feature you are asking for
251
I assume you mean shim -> sd-stub boot chain. Because shim -> sd-boot -> st-stub works fine for me.
This one is on shim. It looks like it assumes that what it loads is a boot loader not the (unified) kernel itself. You can easily test this by loading a Mok-signed kernel (not the unified kernel image, just the kernel-provided pe-stub itself) through the efi shell:
$ shimx64.efi linux-x64-signed.efi
This will happily work when not in secure boot, but give you a security violation with it enabled. At this point, the unified kernel image using sd-stub cannot work either for the very same reason.
On x86 we aren't even using StartImage to launch the payload as we're using the kernel's efi handover protocol.
On other arches we currently also don't use LoadImage/StartImage because we explicitly wanted to support booting a payload that wasn't signed (we rely on the unified image itself being trusted already as it's already running at this point, so the payload must be trusted then too).
There is a way to use LoadImage/StartImage with secure boot using the security arch protocol, and I kinda wanna switch the generic patch to that. But I am currently not 100% that would work with shim as I think we still have to call into shim to verify the payload. But we explicitly want to support unsigned payloads (since they're trusted implicitly already).
So yeah, I don't think there is something we can do here, other than calling this boot path unsupported. People should consider enrolling their your own keys, as booting a db-signed sd-stub directly works perfectly fine.
I assume you mean
shim -> sd-stubboot chain. Becauseshim -> sd-boot -> st-stubworks fine for me.
Yes, it is about shim -> sd-stub boot chain.
I don't think there is something we can do here
Just calling shim verify on any data is enough. As long as the function is called, regardless of the return value, shim will consider the bootloader to be participating.
Just calling shim verify on any data is enough. As long as the function is called, regardless of the return value, shim will consider the bootloader to be participating.
Oh dear, you're right about that. shim is so stupid. 🤦
I am not too sure this is really by design. I can certainly add a call to shim with dummy (or the real payload) data to verify. But I dunno what upstream will think about that.
@vathpela Is it okay for sd-stub to do this?
I am not too sure this is really by design. I can certainly add a call to shim with dummy (or the real payload) data to verify. But I dunno what upstream will think about that.
@vathpela Is it okay for sd-stub to do this?
I'd rather add a heuristic to identify the unified kernel image, and relax the check on that basis. Though tbh we're working on obsoleting this check anyway, so there may be no point in adding this.
I'd rather add a heuristic to identify the unified kernel image, and relax the check on that basis. Though tbh we're working on obsoleting this check anyway, so there may be no point in adding this.
If you do decide to go that route, the easiest way would be to check for a .sdmagic section, which should contain something like #### LoaderInfo: systemd-stub $VERSION ####.
Hmm, I was thinking of adding a new PE section .uname that contains the uname -r string to unified kernels. We could use this here as a generic (i.e. systemd-stub independent) way to detect if something is a (unified) kernel or not.
(My other usecase for that section is that sd-boot can safely extract kernel version info from unified PE binaries, for presentation in the menu. So that .osrel tells us something about the OS a kernel belongs to, and .uname about the kernel itself.)
@vathpela would recognizing unified kernels via such a .uname PE section work for you?
Yeah, that sounds fine to me.
What's the status of this ticket? If I read correctly, the problem could be addressed, but requires a development in shim?
The .uname PE section has been around for a long time now in our tools. No idea about the shim side of things.
As of Shim 16.1 (out soon (TM)) this now works out of the box