From 12caf7271655e16030e34279b1fb0b29a592f6ad Mon Sep 17 00:00:00 2001 From: =?utf8?q?=D0=94=D0=B0=D0=BC=D1=98=D0=B0=D0=BD=20=D0=93=D0=B5=D0=BE?= =?utf8?q?=D1=80=D0=B3=D0=B8=D0=B5=D0=B2=D1=81=D0=BA=D0=B8?= Date: Mon, 29 Nov 2021 22:44:01 +0100 Subject: [PATCH] bootctl: optionally install .signed efi file if /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed exists install that instead of /usr/lib/systemd/boot/efi/systemd-bootx64.efi the idea is that SecureBoot tooling can create the efi.signed file whenever /usr/lib/systemd/boot/efi/systemd-bootx64.efi from the package is updated. --- man/bootctl.xml | 8 ++++++++ src/boot/bootctl.c | 22 ++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/man/bootctl.xml b/man/bootctl.xml index a0be688321..c50f458bbc 100644 --- a/man/bootctl.xml +++ b/man/bootctl.xml @@ -286,6 +286,14 @@ + + Signed .efi files + bootctl and will look for a + systemd-boot file ending with the .efi.signed suffix first, and copy + that instead of the normal .efi file. This allows distributions or end-users to provide + signed images for UEFI SecureBoot. + + Exit status On success, 0 is returned, a non-zero failure code otherwise. diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index 07ad949a0c..51d304ea04 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -628,14 +628,19 @@ static int create_subdirs(const char *root, const char * const *subdirs) { static int copy_one_file(const char *esp_path, const char *name, bool force) { const char *e; - char *p, *q; + char *p, *q, *dest_name, *s; int r; + dest_name = strdupa_safe(name); + s = endswith_no_case(dest_name, ".signed"); + if (s) + *s = 0; + p = strjoina(BOOTLIBDIR "/", name); - q = strjoina(esp_path, "/EFI/systemd/", name); + q = strjoina(esp_path, "/EFI/systemd/", dest_name); r = copy_file_with_version_check(p, q, force); - e = startswith(name, "systemd-boot"); + e = startswith(dest_name, "systemd-boot"); if (e) { int k; char *v; @@ -664,9 +669,18 @@ static int install_binaries(const char *esp_path, bool force) { FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read \""BOOTLIBDIR"\": %m")) { int k; - if (!endswith_no_case(de->d_name, ".efi")) + if (!endswith_no_case(de->d_name, ".efi") && !endswith_no_case(de->d_name, ".efi.signed")) continue; + /* skip the .efi file, if there's a .signed version of it */ + if (endswith_no_case(de->d_name, ".efi")) { + _cleanup_free_ const char *s = strjoin(BOOTLIBDIR, "/", de->d_name, ".signed"); + if (!s) + return log_oom(); + if (access(s, F_OK) >= 0) + continue; + } + k = copy_one_file(esp_path, de->d_name, force); /* Don't propagate an error code if no update necessary, installed version already equal or * newer version, or other boot loader in place. */ -- 2.25.1