Kexec Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Bhupesh Sharma <bhsharma@redhat.com>
To: James Morse <james.morse@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	matthewgarrett@google.com, Will Deacon <will.deacon@arm.com>,
	AKASHI Takahiro <takahiro.akashi@linaro.org>,
	Bhupesh SHARMA <bhupesh.linux@gmail.com>,
	"kexec@lists.infradead.org" <kexec@lists.infradead.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [Query] arm64: Right approach to support Image.gz file type via kexec_file_load()
Date: Mon, 24 Jun 2019 11:29:11 +0530	[thread overview]
Message-ID: <96b0ca14-48ad-ff15-8562-807893bc8124@redhat.com> (raw)
In-Reply-To: <102e8c0a-d69a-81ee-5652-85a2b901230a@arm.com>

Hi James,

Many thanks for your inputs. Please see my comments inline:

On 06/20/2019 08:58 PM, James Morse wrote:
> Hi Bhupesh,
> 
> 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
> 
> 
>> I can figure out two ways to address this:
>>
>> 1. Add support in user-space kexec-tools (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). Copy the contents of Image.gz to a temporary file.
>> b). Decompress (gunzip-decompress) the contents inside the temporary file.
>> c). Pass the 'fd' of the temporary file to the kernel space. So basically the kernel space
>> still gets a decompressed kernel image to load via kexec_tools
> 
> Sounds reasonable.
> (I guess you need to decompress it first to know the size to pass to kexec_file_load(),
> hence the intermediate copy)

That's correct.

>> 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

I generally use 'certs/signing_key.pem' [which is intended to be used
for module signing (CONFIG_MODULE_SIG)], as ${KEY} and ${CERT} for test 
purposes.

Now if CONFIG_KEXEC_VERIFY_SIG is enabled, kexec_file_load() invokes an 
arch-defined (and hence file-format-specific) hook function to check for 
the validity of kernel binary. So a normal 'kexec -s' invocation with 
the signed Image works fine with the current upstream code (and latest 
upstream kexec-tools)

$ kexec -s -l Image.signed --initrd=/boot/initramfs-`uname -r`.img 
--reuse-cmdline

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

- 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.

[1] https://build.opensuse.org/package/show/home:jejb1:UEFI/sbsigntools

>>   - Passing decompressed image from user-space requires the kernel to read large amount of
>> data from the user-space.
> 
> The kernel can't decompress itself, so this large amount of data has to be moved at some
> point.
> 
> 
>> 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>)

  %if %{signkernel}
     # Sign the image if we're using EFI
     # aarch64 kernels are gziped EFI images
     KernelExtension=${KernelImage##*.}
     if [ "$KernelExtension" == "gz" ]; then
         SignImage=${KernelImage%.*}
     else
         SignImage=$KernelImage
     fi

Thanks,
Bhupesh

>> Cons:
>>   - One needs to add a decompress_kernel() -> gunzip() -> inflate() kind-of logic in kernel
>> space to handle gzipp'ed image for arm64.
> 
> We support gzipped initramfs so the code already exists. More of a problem is kdump (which
> we don't yet support), which has to fit in the reserved crashkernel region, and we won't
> know the size of the compressed image until we've decompressed it. (its just fiddly)
> 
> 
>> So, I was wondering which approach should be more suitable - fixing this in user-space v/s
>> fix this in kernel-space.
> 
> As user-space can do this, I think it should!
> 
> 
> Thanks,
> 
> James
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

  reply	other threads:[~2019-06-24  5:59 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-19 21:23 [Query] arm64: Right approach to support Image.gz file type via kexec_file_load() Bhupesh Sharma
2019-06-20 15:28 ` James Morse
2019-06-24  5:59   ` Bhupesh Sharma [this message]
2019-06-24 17:35     ` James Morse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=96b0ca14-48ad-ff15-8562-807893bc8124@redhat.com \
    --to=bhsharma@redhat.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=bhupesh.linux@gmail.com \
    --cc=catalin.marinas@arm.com \
    --cc=james.morse@arm.com \
    --cc=kexec@lists.infradead.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=matthewgarrett@google.com \
    --cc=takahiro.akashi@linaro.org \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox