Hi Bhupesh, On 24/06/2019 06:59, Bhupesh Sharma wrote: > On 06/20/2019 08:58 PM, James Morse wrote: >> On 19/06/2019 22:23, Bhupesh Sharma wrote: >>> Since most distributions use 'make zinstall' rule inside 'arch/arm64/boot/Makefile' (see >>> [1] for details) to install the arm64 Image.gz compressed file inside the boot destination >>> directory (for e.g. /boot), currently we cannot use kexec_file_load() to load vmlinuz (or >>> Image.gz): >> >> It's not just kexec_file_load(), we don't support booting from compressed or elf image >> formats either: the bootloader has to decompress any Image.gz before it can run it. > > That's correct. > >>> ... kernel returns -EINVAL error value, as it is not able to locate the magic number >>> =0x644d5241, which is expected in the 64-byte header of the decompressed kernel image >>> This seems to have the following pros and cons, which I can think of: >>> >>> Pros: >>> - Changes can be handled in the user-space (kexec_tools) and no changes are required in >>> kernel space for handling the unsigned/non-secure boot case. >>> >>> Cons: >>> - One obvious issue is how to handle the signed kernel Image.gz, because signature >>> verification is managed inside the kernel, so handling a signed Image.gz would require >>> kernel intervention eventually. >> How do you sign an Image.gz? Isn't the signature written into the PE header? > That's correct, normally in user-land one uses standard signing utilities like the sbsign > tools (see [1]). For example I use the following method to sign the decompressed kernel > Image: > > $ sbsign --key ${KEY} --cert ${CERT} Image --output Image.signed | morse@eglon:~/kernel/linux/build_arm64$ sbsign --key certs/signing_key.pem --cert \ | certs/signing_key.pem arch/arm64/boot/Image.gz | Invalid DOS header magic ... because that gzip file isn't a PE32+ that can be loaded by UEFI. > The problem happens when we have a Image.gz instead of a decompressed Image in distro > environments. > > Now the process becomes a lot more complicated: > > - User uses sbsign tool to sign Image.gz, lets call the resulting file as Image.gz.signed Secure Boot is the reason for all this signature stuff. Having only one way these things get signed means it will work on any platform that supports signatures. Supporting multiple formats means potentially multiple, conflicting, signatures. Image.gz isn't a PE32+ file, so wherever sbsign puts the signature, it isn't somewhere the kernel or UEFI know how to validate it. > - kexec_file_load() is invoked using a command line resembling something like: > > $ kexec -s -l Image.gz.signed --initrd=/boot/initramfs-`uname -r`.img --reuse-cmdline > > - Now since kexec_tools (user land) has no support for parsing the signature appended > before the Image.gz file (using which it creates a decompressed Image file) and then to > re-sign the resulting Image file (before it is passed as a fd to the syscall), I am not > sure how this can be handled in user-land appropriately. Surely the right thing to do here is unzip the file, sign it, re-compress it. It has been compressed to save space. The bootloader/grub has to uncompress it before if can get get UEFI to boot it. I'm pretty sure you can't point the efi boot variables at a gzip file. (UEFI has its own compression scheme in appendix H, I can't find any mention of gzip in the spec) >>> 2. Add support in kernel (for which I have a RFC patch ready), which handles an 'Image.gz' >>> being passed via kexec_file_load(), using an approach as follows: >>> >>> a). Define a 'arch_kexec_kernel_image_probe' for arm64, which overrides the __weak >>> definition in 'kernel/kexec_file.c' >>> b). Inside 'arch_kexec_kernel_image_probe' for arm64, check if we have been passed a >>> magic header 0x1f, 0x8b (\037 \213) which indicates a 'gzip format' Image file. >>> b). Decompress the contents inside a buffer using a decompress_kernel() -> gunzip() -> >>> inflate() logic. >>> >>> This seems to have the following pros and cons, which I can think of: >>> >>> Pros: >>> - Handling signed Image.gz becomes easier in the kernel itself. >> >> I don't follow: you can't boot this, so why would you sign it? > > > Because that's what most distributions do normally (I share some signing > rules as a reference below) - if the gzipped EFI images are present then they sign them via > pesign tool (see <http://manpages.ubuntu.com/manpages/bionic/man1/pesign.1.html>) Do they expect platform firmware to boot these? It doesn't work for me: | FS0:\> Image.gz | Unloading driver at 0x00000000000 | Error reported: Unsupported | FS0:\> Image | Loading driver at 0x087F9180000 EntryPoint=0x087FA445F98 | EFI stub: Booting Linux Kernel... It's grub's gzip module that does the decompression. In the same way we expect kexec-tools to decompress the blob to feed kexec_file_load the kernel Image. If you decompress the Image.gz, sign it, re-compress it it should all just work. Thanks, James _______________________________________________ kexec mailing list kexec@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/kexec