bootctl: optionally install .signed efi file
authorДамјан Георгиевски <gdamjan@gmail.com>
Mon, 29 Nov 2021 21:44:01 +0000 (22:44 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 8 Dec 2021 21:21:34 +0000 (22:21 +0100)
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
src/boot/bootctl.c

index a0be688321dffef2245d97dbbdc025454fbf68b2..c50f458bbc7ca5c26c81b2e7f80e279bff72f5d2 100644 (file)
     </variablelist>
   </refsect1>
 
+  <refsect1>
+    <title>Signed .efi files</title>
+    <para><command>bootctl</command> <option>install</option> and <option>update</option> will look for a
+    <command>systemd-boot</command> file ending with the <literal>.efi.signed</literal> suffix first, and copy
+    that instead of the normal <literal>.efi</literal> file. This allows distributions or end-users to provide
+    signed images for UEFI SecureBoot.</para>
+  </refsect1>
+
   <refsect1>
     <title>Exit status</title>
     <para>On success, 0 is returned, a non-zero failure code otherwise.</para>
index 07ad949a0c69589894515800eac3128c5ca8744e..51d304ea041ba6e12d004b17edd77605232a3f8d 100644 (file)
@@ -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. */