From: Michael A Cassaniti Date: Mon, 8 Aug 2022 13:03:37 +0000 (+1000) Subject: Sign systemd-boot EFI binaries under /usr X-Git-Tag: v14~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=90fe5d87f555baa0bcee29dcadeb68ed5fc9ec73;p=thirdparty%2Fmkosi.git Sign systemd-boot EFI binaries under /usr If secure boot signing is enabled with UEFI then `systemd-boot` binaries which are at `/usr/lib/systemd/boot/efi` should be signed with the same signing key that is used for EFI binaries within the ESP. In comparison to signed ESP binaries, the '.signed' extension will be kept. Without this change, any tool that copies these binaries into the ESP will (likely) be copying an unsigned copy of `systemd-boot`. The service `systemd-boot-update.service` is just one example of a service that will regularly attempt to update `systemd-boot` within the ESP. --- diff --git a/mkosi/__init__.py b/mkosi/__init__.py index eeb5d7ab4..6ef2c0b11 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -4041,9 +4041,11 @@ def install_unified_kernel( def secure_boot_sign( config: MkosiConfig, state: MkosiState, + directory: Path, for_cache: bool, cached: bool, mount: Callable[[], ContextManager[None]], + replace: bool = False, ) -> None: if state.do_run_build_script: return @@ -4057,28 +4059,27 @@ def secure_boot_sign( return with mount(): - for path, _, filenames in os.walk(state.root / "efi"): - for i in filenames: - if not i.endswith(".efi") and not i.endswith(".EFI"): - continue + for f in itertools.chain(directory.glob('*.efi'), directory.glob('*.EFI')): + if os.path.exists(f"{f}.signed"): + MkosiPrinter.info(f"Not overwriting existing signed EFI binary {f}.signed") + continue - with complete_step(f"Signing EFI binary {i} in ESP…"): - p = os.path.join(path, i) - - run( - [ - "sbsign", - "--key", - config.secure_boot_key, - "--cert", - config.secure_boot_certificate, - "--output", - p + ".signed", - p, - ], - ) + with complete_step(f"Signing EFI binary {f}…"): + run( + [ + "sbsign", + "--key", + config.secure_boot_key, + "--cert", + config.secure_boot_certificate, + "--output", + f"{f}.signed", + f, + ], + ) - os.rename(p + ".signed", p) + if replace: + os.rename(f"{f}.signed", f) def extract_unified_kernel( @@ -7215,6 +7216,9 @@ def build_image( sshkey = setup_ssh(config, state, for_cache, cached_tree) setup_netdev(config, state, cached_tree) run_postinst_script(config, state, loopdev, for_cache) + # Sign systemd-boot / sd-boot EFI binaries + secure_boot_sign(config, state, state.root / 'usr/lib/systemd/boot/efi', + for_cache, cached, mount=contextlib.nullcontext) if cleanup: remove_packages(config, state.root) @@ -7267,7 +7271,9 @@ def build_image( root_read_only=True) install_unified_kernel(config, state, root_hash, for_cache, cached, mount) - secure_boot_sign(config, state, for_cache, cached, mount) + # Sign EFI binaries under these directories within the ESP + for esp_dir in ['efi/EFI/BOOT', 'efi/EFI/systemd', 'efi/EFI/Linux']: + secure_boot_sign(config, state, state.root / esp_dir, for_cache, cached, mount, replace=True) split_kernel = ( extract_unified_kernel(config, state, for_cache, mount) if config.split_artifacts