[systemd-devel] shim 16 breaking systemd stub and next steps
Heinrich Schuchardt
heinrich.schuchardt at canonical.com
Thu Mar 20 19:33:31 UTC 2025
On 3/20/25 15:46, Alexander Graf wrote:
> On 20.03.25 13:08, Luca Boccassi wrote:
>> On Thu, 20 Mar 2025 at 11:00, Mate Kukri <mate.kukri at canonical.com>
>> wrote:
>>>
>>> Hello,
>>>
>>> A new version of the rhboot secure boot shim was released yesterday
>>> https://github.com/rhboot/shim/releases/tag/16.0.
>>>
>>> This version contains an implementation of the
>>> LoadImage/StartImage/Exit/etc API set, which is exposed both via
>>> SystemTable hooks, and a new protocol called the shim loader protocol.
>>> This allows second stage bootloaders to load and execute shim signed
>>> PE binaries the same way as ones signed by firmware keys.
>>>
>>> Unfortunately this also means that systemd-stub will no longer be able
>>> to load its embedded kernel due to relying on overriding the non-UEFI
>>> standard SECURITY2_ARCH_PROTOCOL to avoid verification which the shim
>>> LoadImage implementation of course does not consult.
>>>
>>> I really hope the solution to this won't be another copy pasted PE
>>> loader inside the stub (as one of the big goals of the loader protocol
>>> work was to avoid the multiplication of PE loaders...)
>>> One possible solution is to add a new API to shim to allow loading
>>> previously verified images such as the embedded kernel without further
>>> verification.
>>>
>>> I am looking to hear your thoughts on how to fix this issue.
>>
>> Thanks for the heads-up - the reason we ended up in this situation is
>> ultimately because we didn't coordinate with shim for this workaround,
>
> Let's align on the fact that shim is a giant hack that should not exist
> in the first place :). The only reason we have it is because for some
> reason, people believe that having the same secure boot key for every
> application in the world is a sensible security posture.
>
> So instead of focusing on (enabling) the shim case, let's make sure we
> don't break the sane case, which is a secure boot boot without shim.
> Either in edk2 or U-Boot. Do the current hacks even work with U-Boot's
> UEFI implementation?
>
>> so I think your suggestion of adding a new API to shim is the best
>> solution. Once a formal API is established, we remove the chances of
>> accidental/unaware breakages going forward, which would be a very
>> positive outcome.
>>
>> And I share your sentiments w.r.t adding yet another NIH
>> reimplementation. It would be really strange if the addition of a
>> protocol results in grub shedding code and removing a local
>> reimplementation and using a common protocol instead, and sd-boot
>> doing the exact opposite...
>
> I disagree. Grub and sd-boot have fundamentally different goals. Grub
> wants to load arbitrary code and needs to ask the system to validate it.
> So it really wants to go through as many authentication and validation
> dances as possible: It effectively wants the LoadImage() call, just that
> because the world with shim is so messed up that it can't actually use it.
>
> Sd-boot on the other hand is already past the verification stage. In the
> normal case, the binary you loaded contained everything you wanted to
> validate. The only part where I suppose that's not true are add-ons.
>
> For the "normal" path, you don't want another loader. You just want to
> jump into the image that is already loaded, but execute a few
> instructions before you do. Better concentrate on that rather than try
> to hack up the loader path to not redo validation and authentication on
> your inner payload.
>
> For add-ons, you effectively have 2 code paths, similar to grub: A
> LoadImage() code path for sane environments and a shim special case for
> shim. But in both you *want* to go through all of the validation and
> authentication logic, because an add-on should impact your measurements.
>
>
> Alex
>
The way systemd-boot bypasses secure boot is not UEFI compliant.
It patches pointers in security protocol interfaces
(EFI_SECURITY_ARCH_PROTOCOL, Security2 Architectural Protocol) provided
by the PI specification.
The PI specification gives no guarantee that the protocol interface is
in writable memory. The MMU could be set up to make it read-only. So
systemd-boot may simply crash.
The UEFI specification does not require that the PI specification is
implemented at all. This is why systemd-boot's secure boot never worked
on U-Boot.
The UEFI specification explicitly says:
"On the other hand, firmware-internal interfaces, such as those defined
by the PI Specification, are produced and consumed by firmware only, and
are not considered interfaces that a UEFI aware OS can connect to,
interact with, or depend on."
This confirms that systemd-boot is not UEFI compliant and therefore
should not be expected to work on UEFI compliant firmware.
Shim overwriting the system-table is also a hack which is not backed by
the UEFI standard. It would have been preferable to create a new
protocol which exposes shim's LoadImage, StartImage, ExitImage and let
GRUB or any other bootloader consume it.
There is no good reason why shim should not load what could have been
loaded directly by the firmware. If shim fails to verify a binary
against its own database, it should fall back to the firmware
implementations of said boot services.
Best regards
Heinrich
More information about the systemd-devel
mailing list