]> git.proxmox.com Git - grub2.git/commitdiff
If running under UEFI secure boot, attempt to use linuxefi loader
authorColin Watson <cjwatson@ubuntu.com>
Mon, 13 Jan 2014 12:13:20 +0000 (12:13 +0000)
committerColin Watson <cjwatson@debian.org>
Mon, 13 Jan 2014 12:29:00 +0000 (12:29 +0000)
Author: Steve Langasek <steve.langasek@canonical.com>
Forwarded: no
Last-Update: 2013-12-20

Patch-Name: linuxefi_non_sb_fallback.patch

grub-core/loader/i386/efi/linux.c
grub-core/loader/i386/linux.c

index 26a958c4398648e133c1fe70874ce7fdcd6216b1..eb4ba9608e28a3e16546f05e5a33e88e701ff70a 100644 (file)
@@ -234,7 +234,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 
   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 31fb91e2c7307b9ef63ded7c01e70aedcd8ea53e..2380642e71dd0bb1a99118d1d7b375d01b4598ea 100644 (file)
@@ -76,6 +76,8 @@ static grub_size_t maximal_cmdline_size;
 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;
@@ -690,6 +692,41 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 
   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"));
@@ -1052,6 +1089,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
   grub_err_t err;
   struct grub_linux_initrd_context initrd_ctx;
 
+#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"));