systemd/0363-ukify-if-the-specified-kernel-is-not-a-valid-PE-file.patch
Jan Macku ee560ada81 systemd-257-12
Resolves: RHEL-100553,RHEL-103354,RHEL-104555,RHEL-106260,RHEL-44419,RHEL-72701,RHEL-79976,RHEL-97625,RHEL-97762
2025-08-13 13:54:24 +02:00

62 lines
2.6 KiB
Diff

From c164b0ced4b387779a93434717bea4623db8d41c Mon Sep 17 00:00:00 2001
From: Luca Boccassi <luca.boccassi@gmail.com>
Date: Thu, 13 Feb 2025 19:44:12 +0000
Subject: [PATCH] ukify: if the specified kernel is not a valid PE file try to
decompress it
On some distros on some architectures (e.g.: Ubuntu arm64) the kernel is shipped as
a gzipped file, which the UEFI firmware does not understand.
If pefile fails to parse it, try to decompress it.
(cherry picked from commit 0dd03215f1e402092f6c6da213708045e445a9ed)
Related: RHEL-97625
---
src/ukify/ukify.py | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py
index cf35daf821..45ce8e017c 100755
--- a/src/ukify/ukify.py
+++ b/src/ukify/ukify.py
@@ -1110,7 +1110,22 @@ def make_uki(opts: UkifyConfig) -> None:
sign_kernel = opts.sign_kernel
linux = opts.linux
- if opts.linux and sign_args_present:
+ # On some distros, on some architectures, the vmlinuz is a gzip file, so we need to decompress it
+ # if it's not a valid PE file, as it will fail to be booted by the firmware.
+ if linux:
+ try:
+ pefile.PE(linux, fast_load=True)
+ except pefile.PEFormatError:
+ try:
+ decompressed = maybe_decompress(linux)
+ except NotImplementedError:
+ print(f'{linux} is not a valid PE file and cannot be decompressed either', file=sys.stderr)
+ else:
+ print(f'{linux} is compressed and cannot be loaded by UEFI, decompressing', file=sys.stderr)
+ linux = Path(tempfile.NamedTemporaryFile(prefix='linux-decompressed').name)
+ linux.write_bytes(decompressed)
+
+ if linux and sign_args_present:
assert opts.signtool is not None
signtool = SignTool.from_string(opts.signtool)
@@ -1120,12 +1135,12 @@ def make_uki(opts: UkifyConfig) -> None:
if sign_kernel:
linux_signed = tempfile.NamedTemporaryFile(prefix='linux-signed')
+ signtool.sign(os.fspath(linux), os.fspath(Path(linux_signed.name)), opts=opts)
linux = Path(linux_signed.name)
- signtool.sign(os.fspath(opts.linux), os.fspath(linux), opts=opts)
- if opts.uname is None and opts.linux is not None:
+ if opts.uname is None and linux is not None:
print('Kernel version not specified, starting autodetection 😖.', file=sys.stderr)
- opts.uname = Uname.scrape(opts.linux, opts=opts)
+ opts.uname = Uname.scrape(linux, opts=opts)
uki = UKI(opts.stub)
initrd = join_initrds(opts.initrd)