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
next prev parent 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