grub2/debian/patches/linuxefi_non_sb_fallback.patch
Colin Watson 0d39b369ff Automatically call linuxefi from linux if secure boot is enabled and
the kernel is signed, to hand over to the kernel without calling
ExitBootServices.  Otherwise, linux will fall through to previous
code, call ExitBootServices itself, and boot the kernel normally.
2013-01-29 06:12:13 +00:00

88 lines
2.7 KiB
Diff

Description: If running under UEFI secure boot, attempt to use linuxefi loader
Author: Colin Watson <cjwatson@ubuntu.com>
Author: Steve Langasek <steve.langasek@canonical.com>
Forwarded: no
Last-Update: 2012-10-05
Index: b/grub-core/loader/i386/efi/linux.c
===================================================================
--- a/grub-core/loader/i386/efi/linux.c
+++ b/grub-core/loader/i386/efi/linux.c
@@ -234,7 +234,7 @@
if (! grub_linuxefi_secure_validate (kernel, filelen))
{
- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("%s has invalid signature"), argv[0]);
grub_free (kernel);
goto fail;
}
Index: b/grub-core/loader/i386/linux.c
===================================================================
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -75,6 +75,8 @@
static struct linux_kernel_params linux_params;
static char *linux_cmdline;
#ifdef GRUB_MACHINE_EFI
+static int using_linuxefi;
+static grub_command_t initrdefi_cmd;
static grub_efi_uintn_t efi_mmap_size;
#else
static const grub_size_t efi_mmap_size = 0;
@@ -684,6 +686,41 @@
grub_dl_ref (my_mod);
+#ifdef GRUB_MACHINE_EFI
+ using_linuxefi = 0;
+ if (grub_efi_secure_boot ())
+ {
+ /* Try linuxefi first, which will require a successful signature check
+ and then hand over to the kernel without calling ExitBootServices.
+ If that fails, however, fall back to calling ExitBootServices
+ ourselves and then booting an unsigned kernel. */
+ grub_dl_t mod;
+ grub_command_t linuxefi_cmd;
+
+ grub_dprintf ("linux", "Secure Boot enabled: trying linuxefi\n");
+
+ mod = grub_dl_load ("linuxefi");
+ if (mod)
+ {
+ grub_dl_ref (mod);
+ linuxefi_cmd = grub_command_find ("linuxefi");
+ initrdefi_cmd = grub_command_find ("initrdefi");
+ if (linuxefi_cmd && initrdefi_cmd)
+ {
+ (linuxefi_cmd->func) (linuxefi_cmd, argc, argv);
+ if (grub_errno == GRUB_ERR_NONE)
+ {
+ grub_dprintf ("linux", "Handing off to linuxefi\n");
+ using_linuxefi = 1;
+ return GRUB_ERR_NONE;
+ }
+ grub_dprintf ("linux", "linuxefi failed (%d)\n", grub_errno);
+ grub_errno = GRUB_ERR_NONE;
+ }
+ }
+ }
+#endif
+
if (argc == 0)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -1050,6 +1087,12 @@
int nfiles = 0;
grub_uint8_t *ptr;
+#ifdef GRUB_MACHINE_EFI
+ /* If we're using linuxefi, just forward to initrdefi. */
+ if (using_linuxefi && initrdefi_cmd)
+ return (initrdefi_cmd->func) (initrdefi_cmd, argc, argv);
+#endif
+
if (argc == 0)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));