226 lines
6.7 KiB
Diff
226 lines
6.7 KiB
Diff
|
From 1ff2f31d12f7235423a1eb8a117e0c6f8b2f41c7 Mon Sep 17 00:00:00 2001
|
||
|
From: Michael Chang <mchang@suse.com>
|
||
|
Date: Tue, 4 Jun 2019 12:32:35 +0800
|
||
|
Subject: [PATCH] grub-install: handle signed grub installation on arm64-efi
|
||
|
|
||
|
Use grub2-install to handle signed grub installation for arm64 UEFI secure
|
||
|
boot, the default behavior is auto, which will install signed grub whenever
|
||
|
detected.
|
||
|
|
||
|
Two options, --suse-force-signed and --suse-inhibit-signed, can be used to
|
||
|
override the default auto detecting behavior. The former will force to use
|
||
|
prebuilt signed image and thus will fail if missing, the latter will always use
|
||
|
'mkimage' to create unsigned core image per the user's running environment.
|
||
|
|
||
|
Signed-off-by: Michael Chang <mchang@suse.com>
|
||
|
---
|
||
|
util/grub-install.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||
|
1 file changed, 85 insertions(+), 1 deletion(-)
|
||
|
|
||
|
--- a/util/grub-install.c
|
||
|
+++ b/util/grub-install.c
|
||
|
@@ -85,6 +85,15 @@
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
+ SIGNED_GRUB_INHIBIT,
|
||
|
+ SIGNED_GRUB_AUTO,
|
||
|
+ SIGNED_GRUB_FORCE
|
||
|
+ };
|
||
|
+
|
||
|
+static int signed_grub_mode = SIGNED_GRUB_AUTO;
|
||
|
+
|
||
|
+enum
|
||
|
+ {
|
||
|
OPTION_BOOT_DIRECTORY = 0x301,
|
||
|
OPTION_ROOT_DIRECTORY,
|
||
|
OPTION_TARGET,
|
||
|
@@ -109,6 +118,8 @@
|
||
|
OPTION_NO_BOOTSECTOR,
|
||
|
OPTION_NO_RS_CODES,
|
||
|
OPTION_SUSE_ENABLE_TPM,
|
||
|
+ OPTION_SUSE_FORCE_SIGNED,
|
||
|
+ OPTION_SUSE_INHIBIT_SIGNED,
|
||
|
OPTION_MACPPC_DIRECTORY,
|
||
|
OPTION_ZIPL_DIRECTORY,
|
||
|
OPTION_LABEL_FONT,
|
||
|
@@ -238,6 +249,14 @@
|
||
|
suse_enable_tpm = 1;
|
||
|
return 0;
|
||
|
|
||
|
+ case OPTION_SUSE_FORCE_SIGNED:
|
||
|
+ signed_grub_mode = SIGNED_GRUB_FORCE;
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ case OPTION_SUSE_INHIBIT_SIGNED:
|
||
|
+ signed_grub_mode = SIGNED_GRUB_INHIBIT;
|
||
|
+ return 0;
|
||
|
+
|
||
|
case OPTION_DEBUG:
|
||
|
verbosity++;
|
||
|
return 0;
|
||
|
@@ -300,7 +319,12 @@
|
||
|
N_("Do not apply any reed-solomon codes when embedding core.img. "
|
||
|
"This option is only available on x86 BIOS targets."), 0},
|
||
|
{"suse-enable-tpm", OPTION_SUSE_ENABLE_TPM, 0, 0, N_("install TPM modules"), 0},
|
||
|
-
|
||
|
+ {"suse-force-signed", OPTION_SUSE_FORCE_SIGNED, 0, 0,
|
||
|
+ N_("force installation of signed grub" "%s."
|
||
|
+ "This option is only available on ARM64 EFI targets."), 0},
|
||
|
+ {"suse-inhibit-signed", OPTION_SUSE_INHIBIT_SIGNED, 0, 0,
|
||
|
+ N_("inhibit installation of signed grub. "
|
||
|
+ "This option is only available on ARM64 EFI targets."), 0},
|
||
|
{"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2},
|
||
|
{"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2},
|
||
|
{"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2},
|
||
|
@@ -375,6 +399,22 @@
|
||
|
free (plats);
|
||
|
return ret;
|
||
|
}
|
||
|
+ case OPTION_SUSE_FORCE_SIGNED:
|
||
|
+ {
|
||
|
+ const char *t = get_default_platform ();
|
||
|
+ char *ret;
|
||
|
+ if (grub_strcmp (t, "arm64-efi") == 0)
|
||
|
+ {
|
||
|
+ char *s = grub_util_path_concat (3, grub_util_get_pkglibdir (), t, "grub.efi");
|
||
|
+ char *text2 = xasprintf (" [default=%s]", s);
|
||
|
+ ret = xasprintf (text, text2);
|
||
|
+ free (text2);
|
||
|
+ free (s);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ ret = xasprintf (text, "");
|
||
|
+ return ret;
|
||
|
+ }
|
||
|
case ARGP_KEY_HELP_POST_DOC:
|
||
|
return xasprintf (text, program_name, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME);
|
||
|
default:
|
||
|
@@ -1681,13 +1721,34 @@
|
||
|
|
||
|
char mkimage_target[200];
|
||
|
const char *core_name = NULL;
|
||
|
+ char *signed_imgfile = NULL;
|
||
|
|
||
|
switch (platform)
|
||
|
{
|
||
|
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
|
||
|
+
|
||
|
+ if (signed_grub_mode > SIGNED_GRUB_INHIBIT)
|
||
|
+ {
|
||
|
+ signed_imgfile = grub_util_path_concat (2, grub_install_source_directory, "grub.efi");
|
||
|
+ if (!grub_util_is_regular (signed_imgfile))
|
||
|
+ {
|
||
|
+ if (signed_grub_mode >= SIGNED_GRUB_FORCE)
|
||
|
+ grub_util_error ("signed image `%s' does not exist\n", signed_imgfile);
|
||
|
+ else
|
||
|
+ {
|
||
|
+ free (signed_imgfile);
|
||
|
+ signed_imgfile = NULL;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if (signed_imgfile)
|
||
|
+ fprintf (stderr, _("Use signed file in %s for installation.\n"), signed_imgfile);
|
||
|
+
|
||
|
+ /* fallthrough. */
|
||
|
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_LOONGARCH64_EFI:
|
||
|
case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
|
||
|
case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
|
||
|
@@ -1758,13 +1819,75 @@
|
||
|
core_name);
|
||
|
char *prefix = xasprintf ("%s%s", prefix_drive ? : "",
|
||
|
relative_grubdir);
|
||
|
- if (core_name != mkimage_target)
|
||
|
+ char *grub_efi_cfg = NULL;
|
||
|
+
|
||
|
+ if ((core_name != mkimage_target) && !signed_imgfile)
|
||
|
grub_install_make_image_wrap (/* source dir */ grub_install_source_directory,
|
||
|
/*prefix */ prefix,
|
||
|
/* output */ imgfile,
|
||
|
/* memdisk */ NULL,
|
||
|
have_load_cfg ? load_cfg : NULL,
|
||
|
/* image target */ mkimage_target, 0);
|
||
|
+ else if (signed_imgfile)
|
||
|
+ {
|
||
|
+ FILE *grub_cfg_f;
|
||
|
+
|
||
|
+ grub_install_copy_file (signed_imgfile, imgfile, 1);
|
||
|
+ grub_efi_cfg = grub_util_path_concat (2, platdir, "grub.cfg");
|
||
|
+ grub_cfg_f = grub_util_fopen (grub_efi_cfg, "wb");
|
||
|
+ if (!grub_cfg_f)
|
||
|
+ grub_util_error (_("Can't create file: %s"), strerror (errno));
|
||
|
+
|
||
|
+ if (have_abstractions)
|
||
|
+ {
|
||
|
+ fprintf (grub_cfg_f, "set prefix=(%s)%s\n", grub_drives[0], relative_grubdir);
|
||
|
+ fprintf (grub_cfg_f, "set root=%s\n", grub_drives[0]);
|
||
|
+ }
|
||
|
+ else if (prefix_drive)
|
||
|
+ {
|
||
|
+ char *uuid = NULL;
|
||
|
+ if (grub_fs->fs_uuid && grub_fs->fs_uuid (grub_dev, &uuid))
|
||
|
+ {
|
||
|
+ grub_print_error ();
|
||
|
+ grub_errno = 0;
|
||
|
+ uuid = NULL;
|
||
|
+ }
|
||
|
+ if (!uuid)
|
||
|
+ grub_util_error ("cannot find fs uuid for %s", grub_fs->name);
|
||
|
+
|
||
|
+ fprintf (grub_cfg_f, "search --fs-uuid --set=root %s\n", uuid);
|
||
|
+ fprintf (grub_cfg_f, "set prefix=($root)%s\n", relative_grubdir);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (have_load_cfg)
|
||
|
+ {
|
||
|
+ size_t len;
|
||
|
+ char *buf;
|
||
|
+
|
||
|
+ FILE *fp = grub_util_fopen (load_cfg, "rb");
|
||
|
+ if (!fp)
|
||
|
+ grub_util_error (_("Can't read file: %s"), strerror (errno));
|
||
|
+
|
||
|
+ fseek (fp, 0, SEEK_END);
|
||
|
+ len = ftell (fp);
|
||
|
+ fseek (fp, 0, SEEK_SET);
|
||
|
+ buf = xmalloc (len);
|
||
|
+
|
||
|
+ if (fread (buf, 1, len, fp) != len)
|
||
|
+ grub_util_error (_("cannot read `%s': %s"), load_cfg, strerror (errno));
|
||
|
+
|
||
|
+ if (fwrite (buf, 1, len, grub_cfg_f) != len)
|
||
|
+ grub_util_error (_("cannot write `%s': %s"), grub_efi_cfg, strerror (errno));
|
||
|
+
|
||
|
+ free (buf);
|
||
|
+ fclose (fp);
|
||
|
+ }
|
||
|
+
|
||
|
+ fprintf (grub_cfg_f, "source ${prefix}/grub.cfg\n");
|
||
|
+ fclose (grub_cfg_f);
|
||
|
+ free (signed_imgfile);
|
||
|
+ signed_imgfile = NULL;
|
||
|
+ }
|
||
|
/* Backward-compatibility kludges. */
|
||
|
switch (platform)
|
||
|
{
|
||
|
@@ -2061,6 +2184,13 @@
|
||
|
grub_set_install_backup_ponr ();
|
||
|
|
||
|
free (dst);
|
||
|
+ if (grub_efi_cfg)
|
||
|
+ {
|
||
|
+ dst = grub_util_path_concat (2, efidir, "grub.cfg");
|
||
|
+ grub_install_copy_file (grub_efi_cfg, dst, 1);
|
||
|
+ free (dst);
|
||
|
+ free (grub_efi_cfg);
|
||
|
+ }
|
||
|
}
|
||
|
if (!removable && update_nvram)
|
||
|
{
|