1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-24 14:50:17 +03:00

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.
This commit is contained in:
Luca Boccassi 2025-02-13 19:44:12 +00:00
parent a6d51ae582
commit 0dd03215f1

View File

@ -1297,7 +1297,22 @@ def make_uki(opts: UkifyConfig) -> None:
linux = opts.linux
combined_sigs = '{}'
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)
@ -1307,12 +1322,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.join_pcrsig if opts.join_pcrsig else opts.stub)
initrd = join_initrds(opts.initrd)