From 0bd31f4c7468f0b42ff6673f47112b9167c6381c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jan 2014 12:13:22 +0000 Subject: Install signed images if UEFI Secure Boot is enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Author: Stéphane Graber Author: Steve Langasek Author: Linn Crosetto Author: Mathieu Trudel-Lapierre Forwarded: no Last-Update: 2023-01-15 Patch-Name: install-signed.patch --- util/grub-install.c | 212 ++++++++++++++++++++++++++++++++------------ 1 file changed, 153 insertions(+), 59 deletions(-) Index: grub.git/util/grub-install.c =================================================================== --- grub.git.orig/util/grub-install.c +++ grub.git/util/grub-install.c @@ -79,6 +79,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 { @@ -109,7 +110,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; @@ -233,6 +236,14 @@ argp_parser (int key, char *arg, struct 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?")); @@ -302,6 +313,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} }; @@ -832,7 +851,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; @@ -1102,6 +1122,39 @@ 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; + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + efi_suffix = "riscv32"; + efi_suffix_upper = "RISCV32"; + break; + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + efi_suffix = "riscv64"; + efi_suffix_upper = "RISCV64"; + break; + default: + break; + } if (removable) { /* The specification makes stricter requirements of removable @@ -1110,66 +1163,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; - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - efi_file = "BOOTRISCV32.EFI"; - break; - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: - efi_file = "BOOTRISCV64.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; - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - efi_file = "grubriscv32.efi"; - break; - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: - efi_file = "grubriscv64.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); @@ -1375,14 +1378,38 @@ 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; + 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). */ @@ -1927,7 +1957,72 @@ 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); + if (!removable) + 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); grub_set_install_backup_ponr ();