[PATCH 0/2] Sign the Image which is zboot's payload

Ard Biesheuvel ardb at kernel.org
Mon Sep 25 08:55:46 UTC 2023


On Mon, 25 Sept 2023 at 03:01, Pingfan Liu <piliu at redhat.com> wrote:
>
> On Fri, Sep 22, 2023 at 1:19 PM Jan Hendrik Farr <kernel at jfarr.cc> wrote:
> >
...
> > I missed some of the earlier discussion about this zboot kexec support.
> > So just let me know if I'm missing something here. You were exploring
> > these two options in getting this supported:
> >
> > 1. Making kexec_file_load do all the work.
> >
> > This option makes the signature verification easy. kexec_file_load
> > checks the signature on the pe file and then extracts it and does the
> > kexec.
> >
> > This is similar to how I'm approaching UKI support in [1].
> >
>
> Yes, that is my original try.
>
> > 2. Extract in userspace and pass decompressed kernel to kexec_file_load
> >
> > This option requires the decompressed kernel to have a valid signature on
> > it. That's why this patch adds the ability to add that signature to the
> > kernel contained inside the zboot image.
> >
>
> You got it.
>
> > This option would not make sense for UKI support as it would not
> > validate the signature with respect to the initrd and cmdline that it
> > contains. Am I correct in thinking that there is no similar issue with
> > zboot images? They don't contain any more information besides the kernel
> > that is intended to be securely signed, right? Do you have a reference
>
> If using my second method, it means to unpack the UKI image in user
> space, and pass the kernel image, initrd and cmdline through
> kexec_file_load interface. If the UKI can have signature on the initrd
> and cmdline, we extend the capability of that interface to check those
> verification.
>
> > for the zboot image layout somewhere?
> >
>
> Sorry that maybe there is no document. I understand them through the code.
> The zboot image, aka, vmlinuz.efi looks like:
> PE header, which is formed manually in arch/arm64/kernel/head.S
> EFI decompressor, which consists of
> drivers/firmware/efi/libstub/zboot.c and libstub
> Image.gz, which is formed by compressing Image as instructed in Makefile.zboot
>
>

Indeed, this is currently only documented in code. zboot is a PE
executable that decompresses the kernel and boots it, but it also
carries the base and size of the compressed payload in its header,
along with the compression type so non-EFI loaders can run it as well
(QEMU implements this for gzip on arm64)

> > > I hesitate to post this series,
> >
> > I appreciate you sending it, it's helping the discussion along.
> >

Absolutely. RFCs are important because nobody knows how exactly the
code will look until someone takes the time to implement it. So your
work on this is much appreciated, even if we may decide to take
another approach down the road.

> > > [...] since Ard has recommended using an
> > > emulated UEFI boot service to resolve the UKI kexec load problem [1].
> > > since on aarch64, vmlinuz.efi has faced the similar issue at present.
> > > But anyway, I have a crude outline of it and am sending it out for
> > > discussion.
> >
> > The more I'm thinking about it, the more I like Ard's idea. There's now
> > already two different formats trying to be added to kexec that are
> > pretty different from each other, yet they both have the UEFI interface
> > in common. I think if the kernel supported kexec'ing EFI applications
> > that would be a more flexible and forward-looking approach. It's a
>
> Yes, I agree. That method is attractive, originally I had a try when
> Ard suggested it but there was no clear boundary on which boot service
> should be implemented for zboot, so I did not move on along that
> direction.
>
> Now, UKI poses another challenge to kexec_file_load, and seems to
> require more than zboot. And it appears that Ard's approach is a
> silver bullet for that issue.
>

Yes, it looks appealing but it will take some time to iterate on ideas
and converge on an implementation.

> > standard that both zboot and UKI as well as all future formats for UEFI
> > platforms will support anyways. So while it's more work right now to
> > implement, I think it'll likely pay off.
> >
> > It is significantly more work than the other options though. So I think
> > before work is started on it, it would be nice to get some type of
> > consensus on these things (not an exhaustive list, please feel free to
> > add to it):
> >
>
> I try to answer part of the questions.
>
> > 1. Is it the right approach? It adds a significant amount of userspace
> > API.
>
> My crude assumption: this new stub will replace the purgatory, and I
> am not sure whether kexec-tools source tree will accommodate it. It
> can be signed and checked during the kexec_file_load.
>
> > 2. What subset of the UEFI spec needs/should to be supported?
> > 3. Can we let runtime services still be handled by the firmware after
> > exiting boot services?
>
> I think the runtime services survive through the kexec process. It is
> derived from the real firmware, not related with this stub
>

Yes, this should be possible.

> > 4. How can we debug the stubs that are being invoked?
> > 5. Can we let the EFI binary know that this is a kexec and not a normal
> > bootup. Potentially systemd-stub would want to change how/if it does TPM
> > PCR measurements.
> > ...
> >
>

Not sure whether this matters. The TPM logic is exposed via EFI
protocols, and the kernel could either expose them or not. If it does,
and we execute the EFI stub (sytemd-stub) code all the way through to
ExitBootServices() while executing in the old kernel, we could even
take PCR measurements and display them, giving us secure and measured
boot for kexec.

> Besides these questions, I wonder whether a highly configured EDK2 can
> be used as the stub (ArmVirtQemuKernel.dsc can be the start point).
> But there should be efforts to exclude the drivers which have the MMIO
> access. I saw Ard is active in EDK2, maybe that is the reason why he
> did not pick up EDK2 to serve the stub.
>

I don't think EDK2 is suitable for this - the code style is different,
the license is different and it is simply a lot of code.

What I would prefer is to define a subset of the EFI boot services
that we actually rely on, and perhaps even introduce some other
constraints on the EFI code, e.g., allow it to run unprivileged.

That way, kexec could execute the EFI stub as an ordinary user process
(to some extent), including allocations for the decompressed kernel,
initrd, etc. Finally, the only thing purgatory would need to do is
linearize the populated regions in the VA space and copy them to
physical memory.

This all sounds very high-level, and there may be some difficulties
down the road, but I think this deserves a proper look because it is
an appealing way to make EFI execution idempotent in the context of
kexec, and also reduces the arch-specific logic substantially.



More information about the Linux-security-module-archive mailing list