]> git.proxmox.com Git - grub2.git/commitdiff
Install signed images if UEFI Secure Boot is enabled
authorColin Watson <cjwatson@ubuntu.com>
Mon, 13 Jan 2014 12:13:22 +0000 (12:13 +0000)
committerColin Watson <cjwatson@debian.org>
Fri, 16 Mar 2018 10:56:39 +0000 (10:56 +0000)
Author: Stéphane Graber <stgraber@ubuntu.com>
Author: Steve Langasek <steve.langasek@ubuntu.com>
Author: Linn Crosetto <linn@hpe.com>
Author: Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>
Forwarded: no
Last-Update: 2016-11-01

Patch-Name: install_signed.patch

util/grub-install.c

index 0e1303ee546386e839f9de949606f48cdf9ad295..260dabcfb973417ba5485320fbd15ca3e1b56c8e 100644 (file)
@@ -80,6 +80,7 @@ static char *label_color;
 static char *label_bgcolor;
 static char *product_version;
 static int add_rs_codes = 1;
+static int uefi_secure_boot = 1;
 
 enum
   {
@@ -110,7 +111,9 @@ enum
     OPTION_LABEL_FONT,
     OPTION_LABEL_COLOR,
     OPTION_LABEL_BGCOLOR,
-    OPTION_PRODUCT_VERSION
+    OPTION_PRODUCT_VERSION,
+    OPTION_UEFI_SECURE_BOOT,
+    OPTION_NO_UEFI_SECURE_BOOT
   };
 
 static int fs_probe = 1;
@@ -234,6 +237,14 @@ argp_parser (int key, char *arg, struct argp_state *state)
       bootloader_id = xstrdup (arg);
       return 0;
 
+    case OPTION_UEFI_SECURE_BOOT:
+      uefi_secure_boot = 1;
+      return 0;
+
+    case OPTION_NO_UEFI_SECURE_BOOT:
+      uefi_secure_boot = 0;
+      return 0;
+
     case ARGP_KEY_ARG:
       if (install_device)
        grub_util_error ("%s", _("More than one install device?"));
@@ -303,6 +314,14 @@ static struct argp_option options[] = {
   {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2},
   {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2},
   {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2},
+  {"uefi-secure-boot", OPTION_UEFI_SECURE_BOOT, 0, 0,
+   N_("install an image usable with UEFI Secure Boot. "
+      "This option is only available on EFI and if the grub-efi-amd64-signed "
+      "package is installed."), 2},
+  {"no-uefi-secure-boot", OPTION_NO_UEFI_SECURE_BOOT, 0, 0,
+   N_("do not install an image usable with UEFI Secure Boot, even if the "
+      "system was currently started using it. "
+      "This option is only available on EFI."), 2},
   {0, 0, 0, 0, 0, 0}
 };
 
@@ -821,7 +840,8 @@ main (int argc, char *argv[])
 {
   int is_efi = 0;
   const char *efi_distributor = NULL;
-  const char *efi_file = NULL;
+  const char *efi_suffix = NULL, *efi_suffix_upper = NULL;
+  char *efi_file = NULL;
   char **grub_devices;
   grub_fs_t grub_fs;
   grub_device_t grub_dev = NULL;
@@ -1081,6 +1101,31 @@ main (int argc, char *argv[])
       */
       char *t;
       efi_distributor = bootloader_id;
+      switch (platform)
+       {
+       case GRUB_INSTALL_PLATFORM_I386_EFI:
+         efi_suffix = "ia32";
+         efi_suffix_upper = "IA32";
+         break;
+       case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+         efi_suffix = "x64";
+         efi_suffix_upper = "X64";
+         break;
+       case GRUB_INSTALL_PLATFORM_IA64_EFI:
+         efi_suffix = "ia64";
+         efi_suffix_upper = "IA64";
+         break;
+       case GRUB_INSTALL_PLATFORM_ARM_EFI:
+         efi_suffix = "arm";
+         efi_suffix_upper = "ARM";
+         break;
+       case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+         efi_suffix = "aa64";
+         efi_suffix_upper = "AA64";
+         break;
+       default:
+         break;
+       }
       if (removable)
        {
          /* The specification makes stricter requirements of removable
@@ -1089,54 +1134,16 @@ main (int argc, char *argv[])
             must have a specific file name depending on the architecture.
          */
          efi_distributor = "BOOT";
-         switch (platform)
-           {
-           case GRUB_INSTALL_PLATFORM_I386_EFI:
-             efi_file = "BOOTIA32.EFI";
-             break;
-           case GRUB_INSTALL_PLATFORM_X86_64_EFI:
-             efi_file = "BOOTX64.EFI";
-             break;
-           case GRUB_INSTALL_PLATFORM_IA64_EFI:
-             efi_file = "BOOTIA64.EFI";
-             break;
-           case GRUB_INSTALL_PLATFORM_ARM_EFI:
-             efi_file = "BOOTARM.EFI";
-             break;
-           case GRUB_INSTALL_PLATFORM_ARM64_EFI:
-             efi_file = "BOOTAA64.EFI";
-             break;
-           default:
-             grub_util_error ("%s", _("You've found a bug"));
-             break;
-           }
+         if (!efi_suffix)
+           grub_util_error ("%s", _("You've found a bug"));
+         efi_file = xasprintf ("BOOT%s.EFI", efi_suffix_upper);
        }
       else
        {
          /* It is convenient for each architecture to have a different
             efi_file, so that different versions can be installed in parallel.
          */
-         switch (platform)
-           {
-           case GRUB_INSTALL_PLATFORM_I386_EFI:
-             efi_file = "grubia32.efi";
-             break;
-           case GRUB_INSTALL_PLATFORM_X86_64_EFI:
-             efi_file = "grubx64.efi";
-             break;
-           case GRUB_INSTALL_PLATFORM_IA64_EFI:
-             efi_file = "grubia64.efi";
-             break;
-           case GRUB_INSTALL_PLATFORM_ARM_EFI:
-             efi_file = "grubarm.efi";
-             break;
-           case GRUB_INSTALL_PLATFORM_ARM64_EFI:
-             efi_file = "grubaa64.efi";
-             break;
-           default:
-             efi_file = "grub.efi";
-             break;
-           }
+         efi_file = xasprintf ("grub%s.efi", efi_suffix);
        }
       t = grub_util_path_concat (3, efidir, "EFI", efi_distributor);
       free (efidir);
@@ -1342,14 +1349,41 @@ main (int argc, char *argv[])
        }
     }
 
-  if (!have_abstractions)
+  char *efi_signed = NULL;
+  switch (platform)
+    {
+    case GRUB_INSTALL_PLATFORM_I386_EFI:
+    case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+    case GRUB_INSTALL_PLATFORM_IA64_EFI:
+      {
+       char *dir = xasprintf ("%s-signed", grub_install_source_directory);
+       char *signed_image;
+       if (removable)
+         signed_image = xasprintf ("gcd%s.efi.signed", efi_suffix);
+       else
+         signed_image = xasprintf ("grub%s.efi.signed", efi_suffix);
+       efi_signed = grub_util_path_concat (2, dir, signed_image);
+       break;
+      }
+
+    default:
+      break;
+    }
+
+  if (!efi_signed || !grub_util_is_regular (efi_signed))
+    uefi_secure_boot = 0;
+
+  if (!have_abstractions || uefi_secure_boot)
     {
       if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0)
          || grub_drives[1]
          || (!install_drive
              && platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
          || (install_drive && !is_same_disk (grub_drives[0], install_drive))
-         || !have_bootdev (platform))
+         || !have_bootdev (platform)
+         || uefi_secure_boot)
        {
          char *uuid = NULL;
          /*  generic method (used on coreboot and ata mod).  */
@@ -1871,7 +1905,71 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
       {
        char *dst = grub_util_path_concat (2, efidir, efi_file);
-       grub_install_copy_file (imgfile, dst, 1);
+       if (uefi_secure_boot)
+         {
+           char *shim_signed = NULL;
+           char *mok_signed = NULL, *mok_file = NULL;
+           char *fb_signed = NULL, *fb_file = NULL;
+           char *config_dst;
+           FILE *config_dst_f;
+
+           shim_signed = xasprintf ("/usr/lib/shim/shim%s.efi.signed", efi_suffix);
+           mok_signed = xasprintf ("mm%s.efi.signed", efi_suffix);
+           mok_file = xasprintf ("mm%s.efi", efi_suffix);
+           fb_signed = xasprintf ("fb%s.efi.signed", efi_suffix);
+           fb_file = xasprintf ("fb%s.efi", efi_suffix);
+
+           if (grub_util_is_regular (shim_signed))
+             {
+               char *chained_base, *chained_dst;
+               char *mok_src, *mok_dst, *fb_src, *fb_dst;
+               if (!removable)
+                 {
+                   free (efi_file);
+                   efi_file = xasprintf ("shim%s.efi", efi_suffix);
+                   free (dst);
+                   dst = grub_util_path_concat (2, efidir, efi_file);
+                 }
+               grub_install_copy_file (shim_signed, dst, 1);
+               chained_base = xasprintf ("grub%s.efi", efi_suffix);
+               chained_dst = grub_util_path_concat (2, efidir, chained_base);
+               grub_install_copy_file (efi_signed, chained_dst, 1);
+               free (chained_dst);
+               free (chained_base);
+
+               /* Not critical, so not an error if they are not present (as it
+                  won't be for older releases); but if we have them, make
+                  sure they are installed.  */
+               mok_src = grub_util_path_concat (2, "/usr/lib/shim/",
+                                                   mok_signed);
+               mok_dst = grub_util_path_concat (2, efidir,
+                                                   mok_file);
+               grub_install_copy_file (mok_src,
+                                       mok_dst, 0);
+               free (mok_src);
+               free (mok_dst);
+
+               fb_src = grub_util_path_concat (2, "/usr/lib/shim/",
+                                                   fb_signed);
+               fb_dst = grub_util_path_concat (2, efidir,
+                                                   fb_file);
+               grub_install_copy_file (fb_src,
+                                       fb_dst, 0);
+               free (fb_src);
+               free (fb_dst);
+             }
+           else
+             grub_install_copy_file (efi_signed, dst, 1);
+
+           config_dst = grub_util_path_concat (2, efidir, "grub.cfg");
+           grub_install_copy_file (load_cfg, config_dst, 1);
+           config_dst_f = grub_util_fopen (config_dst, "ab");
+           fprintf (config_dst_f, "configfile $prefix/grub.cfg\n");
+           fclose (config_dst_f);
+           free (config_dst);
+         }
+       else
+         grub_install_copy_file (imgfile, dst, 1);
        free (dst);
       }
       if (!removable && update_nvram)