Install signed images if UEFI Secure Boot is enabled

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: 2021-09-24

Patch-Name: install-signed.patch
This commit is contained in:
Colin Watson 2014-01-13 12:13:22 +00:00 committed by Colin Watson
parent 207c170752
commit a773dd9dff

View File

@ -80,6 +80,7 @@ static char *label_color;
static char *label_bgcolor; static char *label_bgcolor;
static char *product_version; static char *product_version;
static int add_rs_codes = 1; static int add_rs_codes = 1;
static int uefi_secure_boot = 1;
enum enum
{ {
@ -110,7 +111,9 @@ enum
OPTION_LABEL_FONT, OPTION_LABEL_FONT,
OPTION_LABEL_COLOR, OPTION_LABEL_COLOR,
OPTION_LABEL_BGCOLOR, OPTION_LABEL_BGCOLOR,
OPTION_PRODUCT_VERSION OPTION_PRODUCT_VERSION,
OPTION_UEFI_SECURE_BOOT,
OPTION_NO_UEFI_SECURE_BOOT
}; };
static int fs_probe = 1; static int fs_probe = 1;
@ -234,6 +237,14 @@ argp_parser (int key, char *arg, struct argp_state *state)
bootloader_id = xstrdup (arg); bootloader_id = xstrdup (arg);
return 0; 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: case ARGP_KEY_ARG:
if (install_device) if (install_device)
grub_util_error ("%s", _("More than one 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-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}, {"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}, {"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} {0, 0, 0, 0, 0, 0}
}; };
@ -833,7 +852,8 @@ main (int argc, char *argv[])
{ {
int is_efi = 0; int is_efi = 0;
const char *efi_distributor = NULL; 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; char **grub_devices;
grub_fs_t grub_fs; grub_fs_t grub_fs;
grub_device_t grub_dev = NULL; grub_device_t grub_dev = NULL;
@ -1103,6 +1123,39 @@ main (int argc, char *argv[])
*/ */
char *t; char *t;
efi_distributor = bootloader_id; 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) if (removable)
{ {
/* The specification makes stricter requirements of removable /* The specification makes stricter requirements of removable
@ -1111,66 +1164,16 @@ main (int argc, char *argv[])
must have a specific file name depending on the architecture. must have a specific file name depending on the architecture.
*/ */
efi_distributor = "BOOT"; efi_distributor = "BOOT";
switch (platform) if (!efi_suffix)
{
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")); grub_util_error ("%s", _("You've found a bug"));
break; efi_file = xasprintf ("BOOT%s.EFI", efi_suffix_upper);
}
} }
else else
{ {
/* It is convenient for each architecture to have a different /* It is convenient for each architecture to have a different
efi_file, so that different versions can be installed in parallel. efi_file, so that different versions can be installed in parallel.
*/ */
switch (platform) efi_file = xasprintf ("grub%s.efi", efi_suffix);
{
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;
}
} }
t = grub_util_path_concat (3, efidir, "EFI", efi_distributor); t = grub_util_path_concat (3, efidir, "EFI", efi_distributor);
free (efidir); free (efidir);
@ -1376,14 +1379,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) if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0)
|| grub_drives[1] || grub_drives[1]
|| (!install_drive || (!install_drive
&& platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275) && platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
|| (install_drive && !is_same_disk (grub_drives[0], install_drive)) || (install_drive && !is_same_disk (grub_drives[0], install_drive))
|| !have_bootdev (platform)) || !have_bootdev (platform)
|| uefi_secure_boot)
{ {
char *uuid = NULL; char *uuid = NULL;
/* generic method (used on coreboot and ata mod). */ /* generic method (used on coreboot and ata mod). */
@ -1941,6 +1971,70 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_IA64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI:
{ {
char *dst = grub_util_path_concat (2, efidir, efi_file); char *dst = grub_util_path_concat (2, efidir, efi_file);
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); grub_install_copy_file (imgfile, dst, 1);
grub_set_install_backup_ponr (); grub_set_install_backup_ponr ();