SHA256
1
0
forked from pool/grub2

Accepting request 143018 from devel:openSUSE:Factory

- ship a Secure Boot UEFI compatible bootloader (fate#314485)
- added secureboot patches which introduces new linuxefi module
  that is able to perform verifying signed images via exported
  protocol from shim. The insmod command will not function if
  secure boot enabled (as all modules should built in grub.efi
  and signed).
  - grub2-secureboot-add-linuxefi.patch
  - grub2-secureboot-use-linuxefi-on-uefi.patch
  - grub2-secureboot-no-insmod-on-sb.patch
  - grub2-secureboot-provide-linuxefi-config.patch
- Makefile.core.am : support building linuxefi module
- Make grub.efi image that is with all relevant modules incorporated
  and signed, it will be the second stage to the shim loader which
  will verified it when secureboot enabled.
- Make grub.efi's path to align with shim loader's default loader
  lookup path.
- The changes has been verified not affecting any factory instalation,
  but will allow us to run & test secure boot setup manually with shim. (forwarded request 143007 from michael-chang)

OBS-URL: https://build.opensuse.org/request/show/143018
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/grub2?expand=0&rev=52
This commit is contained in:
Stephan Kulow 2012-11-28 09:34:03 +00:00 committed by Git OBS Bridge
parent 9ece58dde9
commit 7127299ebe
7 changed files with 893 additions and 42 deletions

View File

@ -37479,6 +37479,28 @@ appleldr.marker: $(appleldr_module_SOURCES) $(nodist_appleldr_module_SOURCES)
grep 'MARKER' $@.new > $@; rm -f $@.new
endif
if COND_x86_64_efi
platform_PROGRAMS += linuxefi.module
MODULE_FILES += linuxefi.module$(EXEEXT)
linuxefi_module_SOURCES = loader/i386/efi/linux.c lib/cmdline.c ## platform sources
nodist_linuxefi_module_SOURCES = ## platform nodist sources
linuxefi_module_LDADD =
linuxefi_module_CFLAGS = $(AM_CFLAGS) $(CFLAGS_MODULE)
linuxefi_module_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_MODULE)
linuxefi_module_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS_MODULE)
linuxefi_module_CCASFLAGS = $(AM_CCASFLAGS) $(CCASFLAGS_MODULE)
EXTRA_DIST +=
BUILT_SOURCES += $(nodist_linuxefi_module_SOURCES)
CLEANFILES += $(nodist_linuxefi_module_SOURCES)
MOD_FILES += linuxefi.mod
MARKER_FILES += linuxefi.marker
CLEANFILES += linuxefi.marker
linuxefi.marker: $(linuxefi_module_SOURCES) $(nodist_linuxefi_module_SOURCES)
$(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(linuxefi_module_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1)
grep 'MARKER' $@.new > $@; rm -f $@.new
endif
if COND_i386_pc
platform_PROGRAMS += chain.module
MODULE_FILES += chain.module$(EXEEXT)

View File

@ -0,0 +1,485 @@
From: Matthew Garrett <mjg@redhat.com>
Date: 2012-07-10 11:58:52 EDT
Subject: [PATCH] Add support for linuxefi
References: fate#314485
Patch-Mainline: no
Signed-off-by: Michael Chang <mchang@suse.com>
---
grub-core/Makefile.core.def | 8 +
grub-core/kern/efi/mm.c | 32 ++++
grub-core/loader/i386/efi/linux.c | 371 +++++++++++++++++++++++++++++++++++++
include/grub/efi/efi.h | 3 +
include/grub/i386/linux.h | 1 +
5 files changed, 415 insertions(+), 0 deletions(-)
create mode 100644 grub-core/loader/i386/efi/linux.c
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 39e77a4..f9cbfc3 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1415,6 +1415,14 @@ module = {
};
module = {
+ name = linuxefi;
+ efi = loader/i386/efi/linux.c;
+ efi = lib/cmdline.c;
+ enable = i386_efi;
+ enable = x86_64_efi;
+};
+
+module = {
name = chain;
efi = loader/efi/chainloader.c;
i386_pc = loader/i386/pc/chainloader.c;
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
index a2edc84..88b2557 100644
--- a/grub-core/kern/efi/mm.c
+++ b/grub-core/kern/efi/mm.c
@@ -47,6 +47,38 @@ static grub_efi_uintn_t finish_desc_size;
static grub_efi_uint32_t finish_desc_version;
int grub_efi_is_finished = 0;
+/* Allocate pages below a specified address */
+void *
+grub_efi_allocate_pages_max (grub_efi_physical_address_t max,
+ grub_efi_uintn_t pages)
+{
+ grub_efi_status_t status;
+ grub_efi_boot_services_t *b;
+ grub_efi_physical_address_t address = max;
+
+ if (max > 0xffffffff)
+ return 0;
+
+ b = grub_efi_system_table->boot_services;
+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address);
+
+ if (status != GRUB_EFI_SUCCESS)
+ return 0;
+
+ if (address == 0)
+ {
+ /* Uggh, the address 0 was allocated... This is too annoying,
+ so reallocate another one. */
+ address = max;
+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address);
+ grub_efi_free_pages (0, pages);
+ if (status != GRUB_EFI_SUCCESS)
+ return 0;
+ }
+
+ return (void *) ((grub_addr_t) address);
+}
+
/* Allocate pages. Return the pointer to the first of allocated pages. */
void *
grub_efi_allocate_pages (grub_efi_physical_address_t address,
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
new file mode 100644
index 0000000..b79e632
--- /dev/null
+++ b/grub-core/loader/i386/efi/linux.c
@@ -0,0 +1,371 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2012 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/cpu/linux.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <grub/lib/cmdline.h>
+#include <grub/efi/efi.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static grub_dl_t my_mod;
+static int loaded;
+static void *kernel_mem;
+static grub_uint64_t kernel_size;
+static grub_uint8_t *initrd_mem;
+static grub_uint32_t handover_offset;
+struct linux_kernel_params *params;
+static char *linux_cmdline;
+
+#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
+
+#define SHIM_LOCK_GUID \
+ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
+
+struct grub_efi_shim_lock
+{
+ grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
+};
+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
+
+static grub_efi_boolean_t
+grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
+{
+ grub_efi_guid_t guid = SHIM_LOCK_GUID;
+ grub_efi_shim_lock_t *shim_lock;
+
+ shim_lock = grub_efi_locate_protocol(&guid, NULL);
+
+ if (!shim_lock)
+ return 1;
+
+ if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS)
+ return 1;
+
+ return 0;
+}
+
+typedef void(*handover_func)(void *, grub_efi_system_table_t *, struct linux_kernel_params *);
+
+static grub_err_t
+grub_linuxefi_boot (void)
+{
+ handover_func hf;
+ int offset = 0;
+
+#ifdef __x86_64__
+ offset = 512;
+#endif
+
+ hf = (handover_func)((char *)kernel_mem + handover_offset + offset);
+
+ asm volatile ("cli");
+
+ hf (grub_efi_image_handle, grub_efi_system_table, params);
+
+ /* Not reached */
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linuxefi_unload (void)
+{
+ grub_dl_unref (my_mod);
+ loaded = 0;
+ if (initrd_mem)
+ grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(params->ramdisk_size));
+ if (linux_cmdline)
+ grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(params->cmdline_size + 1));
+ if (kernel_mem)
+ grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size));
+ if (params)
+ grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384));
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ grub_file_t *files = 0;
+ int i, nfiles = 0;
+ grub_size_t size = 0;
+ grub_uint8_t *ptr;
+
+ if (argc == 0)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+ goto fail;
+ }
+
+ if (!loaded)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
+ goto fail;
+ }
+
+ files = grub_zalloc (argc * sizeof (files[0]));
+ if (!files)
+ goto fail;
+
+ for (i = 0; i < argc; i++)
+ {
+ grub_file_filter_disable_compression ();
+ files[i] = grub_file_open (argv[i]);
+ if (! files[i])
+ goto fail;
+ nfiles++;
+ size += ALIGN_UP (grub_file_size (files[i]), 4);
+ }
+
+ initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size));
+
+ if (!initrd_mem)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd"));
+ goto fail;
+ }
+
+ params->ramdisk_size = size;
+ params->ramdisk_image = (grub_uint32_t)(grub_uint64_t) initrd_mem;
+
+ ptr = initrd_mem;
+
+ for (i = 0; i < nfiles; i++)
+ {
+ grub_ssize_t cursize = grub_file_size (files[i]);
+ if (grub_file_read (files[i], ptr, cursize) != cursize)
+ {
+ if (!grub_errno)
+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
+ argv[i]);
+ goto fail;
+ }
+ ptr += cursize;
+ grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
+ ptr += ALIGN_UP_OVERHEAD (cursize, 4);
+ }
+
+ params->ramdisk_size = size;
+
+ fail:
+ for (i = 0; i < nfiles; i++)
+ grub_file_close (files[i]);
+ grub_free (files);
+
+ if (initrd_mem && grub_errno)
+ grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(size));
+
+ return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ grub_file_t file = 0;
+ struct linux_kernel_header lh;
+ grub_ssize_t len, start, filelen;
+ void *kernel;
+
+ grub_dl_ref (my_mod);
+
+ if (argc == 0)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+ goto fail;
+ }
+
+ file = grub_file_open (argv[0]);
+ if (! file)
+ goto fail;
+
+ filelen = grub_file_size (file);
+
+ kernel = grub_malloc(filelen);
+
+ if (!kernel)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
+ goto fail;
+ }
+
+ if (grub_file_read (file, kernel, filelen) != filelen)
+ {
+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]);
+ goto fail;
+ }
+
+ if (! grub_linuxefi_secure_validate (kernel, filelen))
+ {
+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
+ grub_free (kernel);
+ goto fail;
+ }
+
+ grub_file_seek (file, 0);
+
+ grub_free(kernel);
+
+ params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384));
+
+ if (! params)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters");
+ goto fail;
+ }
+
+ memset (params, 0, 16384);
+
+ if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
+ {
+ if (!grub_errno)
+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
+ argv[0]);
+ goto fail;
+ }
+
+ if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number"));
+ goto fail;
+ }
+
+ if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors"));
+ goto fail;
+ }
+
+ if (lh.version < grub_cpu_to_le16 (0x020b))
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("kernel too old"));
+ goto fail;
+ }
+
+ if (!lh.handover_offset)
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover"));
+ goto fail;
+ }
+
+ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff,
+ BYTES_TO_PAGES(lh.cmdline_size + 1));
+
+ if (!linux_cmdline)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline"));
+ goto fail;
+ }
+
+ grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
+ grub_create_loader_cmdline (argc, argv,
+ linux_cmdline + sizeof (LINUX_IMAGE) - 1,
+ lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1));
+
+ lh.cmd_line_ptr = (grub_uint32_t)(grub_uint64_t)linux_cmdline;
+
+ handover_offset = lh.handover_offset;
+
+ start = (lh.setup_sects + 1) * 512;
+ len = grub_file_size(file) - start;
+
+ kernel_mem = grub_efi_allocate_pages(lh.pref_address,
+ BYTES_TO_PAGES(lh.init_size));
+
+ if (!kernel_mem)
+ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff,
+ BYTES_TO_PAGES(lh.init_size));
+
+ if (!kernel_mem)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel"));
+ goto fail;
+ }
+
+ if (grub_file_seek (file, start) == (grub_off_t) -1)
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
+ argv[0]);
+ goto fail;
+ }
+
+ if (grub_file_read (file, kernel_mem, len) != len && !grub_errno)
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
+ argv[0]);
+ }
+
+ if (grub_errno == GRUB_ERR_NONE)
+ {
+ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
+ loaded = 1;
+ lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem;
+ }
+
+ memcpy(params, &lh, 2 * 512);
+
+ params->type_of_loader = 0x21;
+
+ fail:
+
+ if (file)
+ grub_file_close (file);
+
+ if (grub_errno != GRUB_ERR_NONE)
+ {
+ grub_dl_unref (my_mod);
+ loaded = 0;
+ }
+
+ if (linux_cmdline && !loaded)
+ grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1));
+
+ if (kernel_mem && !loaded)
+ grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size));
+
+ if (params && !loaded)
+ grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384));
+
+ return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linuxefi)
+{
+ cmd_linux =
+ grub_register_command ("linuxefi", grub_cmd_linux,
+ 0, N_("Load Linux."));
+ cmd_initrd =
+ grub_register_command ("initrdefi", grub_cmd_initrd,
+ 0, N_("Load initrd."));
+ my_mod = mod;
+}
+
+GRUB_MOD_FINI(linuxefi)
+{
+ grub_unregister_command (cmd_linux);
+ grub_unregister_command (cmd_initrd);
+}
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
index e67d92b..1b0e7ae 100644
--- a/include/grub/efi/efi.h
+++ b/include/grub/efi/efi.h
@@ -40,6 +40,9 @@ void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds);
void *
EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address,
grub_efi_uintn_t pages);
+void *
+EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max,
+ grub_efi_uintn_t pages);
void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address,
grub_efi_uintn_t pages);
int
diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
index 9d064c8..c29c5af 100644
--- a/include/grub/i386/linux.h
+++ b/include/grub/i386/linux.h
@@ -139,6 +139,7 @@ struct linux_kernel_header
grub_uint64_t setup_data;
grub_uint64_t pref_address;
grub_uint32_t init_size;
+ grub_uint32_t handover_offset;
} __attribute__ ((packed));
/* Boot parameters for Linux based on 2.6.12. This is used by the setup
--
1.7.3.4

View File

@ -0,0 +1,95 @@
From 7a65d7b558974c89f19afaf0d78b54dc0327f56c Mon Sep 17 00:00:00 2001
From: Matthew Garrett <mjg@redhat.com>
Date: Wed, 15 Aug 2012 09:53:05 -0400
Subject: [PATCH] Don't permit insmod on secure boot
References: fate#314485
Patch-Mainline: no
Signed-off-by: Michael Chang <mchang@suse.com>
---
grub-core/kern/corecmd.c | 9 +++++++++
grub-core/kern/efi/efi.c | 28 ++++++++++++++++++++++++++++
include/grub/efi/efi.h | 1 +
3 files changed, 38 insertions(+)
Index: grub-2.00/grub-core/kern/corecmd.c
===================================================================
--- grub-2.00.orig/grub-core/kern/corecmd.c
+++ grub-2.00/grub-core/kern/corecmd.c
@@ -28,6 +28,10 @@
#include <grub/command.h>
#include <grub/i18n.h>
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/efi.h>
+#endif
+
/* set ENVVAR=VALUE */
static grub_err_t
grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)),
@@ -81,6 +85,13 @@ grub_core_cmd_insmod (struct grub_comman
{
grub_dl_t mod;
+#ifdef GRUB_MACHINE_EFI
+ if (grub_efi_secure_boot()) {
+ //grub_printf("%s\n", N_("Secure Boot forbids insmod"));
+ return 0;
+ }
+#endif
+
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
Index: grub-2.00/grub-core/kern/efi/efi.c
===================================================================
--- grub-2.00.orig/grub-core/kern/efi/efi.c
+++ grub-2.00/grub-core/kern/efi/efi.c
@@ -229,6 +229,34 @@ grub_efi_get_variable (const char *var,
return NULL;
}
+grub_efi_boolean_t
+grub_efi_secure_boot (void)
+{
+ grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
+ grub_size_t datasize;
+ char *secure_boot = NULL;
+ char *setup_mode = NULL;
+ grub_efi_boolean_t ret = 0;
+
+ secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize);
+
+ if (datasize != 1 || !secure_boot)
+ goto out;
+
+ setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize);
+
+ if (datasize != 1 || !setup_mode)
+ goto out;
+
+ if (*secure_boot && !*setup_mode)
+ ret = 1;
+
+ out:
+ grub_free (secure_boot);
+ grub_free (setup_mode);
+ return ret;
+}
+
#pragma GCC diagnostic ignored "-Wcast-align"
/* Search the mods section from the PE32/PE32+ image. This code uses
Index: grub-2.00/include/grub/efi/efi.h
===================================================================
--- grub-2.00.orig/include/grub/efi/efi.h
+++ grub-2.00/include/grub/efi/efi.h
@@ -67,6 +67,7 @@ grub_err_t EXPORT_FUNC (grub_efi_set_vir
void *EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
const grub_efi_guid_t *guid,
grub_size_t *datasize_out);
+grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void);
int
EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1,
const grub_efi_device_path_t *dp2);

View File

@ -0,0 +1,66 @@
From 795ac61cba9674376d745813efdab395e35cff41 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Mon, 26 Nov 2012 15:38:54 +0800
Subject: [PATCH] provide option in config to enable linuxefi
References: fate#314485
Patch-Mainline: no
As linuxefi module requires kernel 3.6 or later which supports EFI
handover protocol, it may not be able to load kernels without that
supports in place.
In case that things would break, and the linuxefi is really too young to
take over the position of "linux" kernel loader module, we introduce a
option GRUB_USE_LINUXEFI in the config and only explicit set it to true
will enable it. Example usage is
GRUB_USE_LINUXEFI=true grub2-mkconfig -o /boot/efi/EFI/opensuse/grub.cfg
This will output a grub.cfg which uses linuxefi in replace of linux and
enable verification of kernel signature if in secureboot enabled and
has shim exported protocols available.
---
util/grub-mkconfig.in | 3 ++-
util/grub.d/10_linux.in | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
index d789fcc..6555944 100644
--- a/util/grub-mkconfig.in
+++ b/util/grub-mkconfig.in
@@ -244,7 +244,8 @@ export GRUB_DEFAULT \
GRUB_SAVEDEFAULT \
GRUB_ENABLE_CRYPTODISK \
GRUB_BADRAM \
- GRUB_CMDLINE_LINUX_RECOVERY
+ GRUB_CMDLINE_LINUX_RECOVERY \
+ GRUB_USE_LINUXEFI
if test "x${grub_cfg}" != "x"; then
rm -f "${grub_cfg}.new"
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
index 807a0db..b2f65c0 100644
--- a/util/grub.d/10_linux.in
+++ b/util/grub.d/10_linux.in
@@ -133,7 +133,7 @@ linux_entry ()
printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
fi
message="$(gettext_printf "Loading Linux %s ..." ${version})"
- if [ -d /sys/firmware/efi ]; then
+ if [ -d /sys/firmware/efi ] && [ "x${GRUB_USE_LINUXEFI}" = "xtrue" ]; then
sed "s/^/$submenu_indentation/" << EOF
echo '$message'
linuxefi ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
@@ -147,7 +147,7 @@ EOF
if test -n "${initrd}" ; then
# TRANSLATORS: ramdisk isn't identifier. Should be translated.
message="$(gettext_printf "Loading initial ramdisk ...")"
- if [ -d /sys/firmware/efi ]; then
+ if [ -d /sys/firmware/efi ] && [ "x${GRUB_USE_LINUXEFI}" = "xtrue" ]; then
sed "s/^/$submenu_indentation/" << EOF
echo '$message'
initrdefi ${rel_dirname}/${initrd}
--
1.7.3.4

View File

@ -0,0 +1,51 @@
From 151b1691fe0cf885df101c6e6a7cb1defc50428b Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 16 Jul 2012 18:57:11 -0400
Subject: [PATCH] Use "linuxefi" and "initrdefi" where appropriate
References: fate#314485
Patch-Mainline: no
Signed-off-by: Michael Chang <mchang@suse.com>
---
util/grub.d/10_linux.in | 18 ++++++++++++++++--
1 files changed, 16 insertions(+), 2 deletions(-)
Index: grub-2.00/util/grub.d/10_linux.in
===================================================================
--- grub-2.00.orig/util/grub.d/10_linux.in
+++ grub-2.00/util/grub.d/10_linux.in
@@ -133,17 +133,31 @@ linux_entry ()
printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
fi
message="$(gettext_printf "Loading Linux %s ..." ${version})"
- sed "s/^/$submenu_indentation/" << EOF
+ if [ -d /sys/firmware/efi ]; then
+ sed "s/^/$submenu_indentation/" << EOF
+ echo '$message'
+ linuxefi ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
+EOF
+ else
+ sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ${args}
EOF
+ fi
if test -n "${initrd}" ; then
# TRANSLATORS: ramdisk isn't identifier. Should be translated.
message="$(gettext_printf "Loading initial ramdisk ...")"
- sed "s/^/$submenu_indentation/" << EOF
+ if [ -d /sys/firmware/efi ]; then
+ sed "s/^/$submenu_indentation/" << EOF
+ echo '$message'
+ initrdefi ${rel_dirname}/${initrd}
+EOF
+ else
+ sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
initrd ${rel_dirname}/${initrd}
EOF
+ fi
fi
sed "s/^/$submenu_indentation/" << EOF
}

View File

@ -1,3 +1,39 @@
-------------------------------------------------------------------
Mon Nov 26 08:26:10 UTC 2012 - mchang@suse.com
- ship a Secure Boot UEFI compatible bootloader (fate#314485)
- added secureboot patches which introduces new linuxefi module
that is able to perform verifying signed images via exported
protocol from shim. The insmod command will not function if
secure boot enabled (as all modules should built in grub.efi
and signed).
- grub2-secureboot-add-linuxefi.patch
- grub2-secureboot-use-linuxefi-on-uefi.patch
- grub2-secureboot-no-insmod-on-sb.patch
- grub2-secureboot-provide-linuxefi-config.patch
- Makefile.core.am : support building linuxefi module
- Make grub.efi image that is with all relevant modules incorporated
and signed, it will be the second stage to the shim loader which
will verified it when secureboot enabled.
- Make grub.efi's path to align with shim loader's default loader
lookup path.
- The changes has been verified not affecting any factory instalation,
but will allow us to run & test secure boot setup manually with shim.
-------------------------------------------------------------------
Thu Nov 22 07:01:31 UTC 2012 - mchang@suse.com
- ship a Secure Boot UEFI compatible bootloader (fate#314485)
- In SLE-11 SP3, don't include any other architecture binaries
except EFI, so we split packages by architecture binaries to
meet the requirement.
- grub2 : common utilties and config etc
- grub2-efi : provide compatibilty to grub2-efi package
- grub2-i386-pc : binaries for x86 legacy pc firmware
- grub2-i386-efi : binaries for ia32 EFI firmware
- grub2-x86_64-efi : binaries for x86_64 firmware
- grub2-powerpc-ieee1275: binaries for powerpc open firmware
-------------------------------------------------------------------
Tue Nov 20 16:14:50 UTC 2012 - arvidjaar@gmail.com

View File

@ -52,22 +52,43 @@ BuildRequires: guile
%define _libdir %{_exec_prefix}/lib
%ifarch ppc ppc64
%define grubcpu powerpc
%define platform ieee1275
%else
%define platform pc
%endif
%ifarch %{ix86} x86_64
%define grubcpu i386
%else
%define grubcpu %{_target_cpu}
%define platform pc
%endif
%define grubarch %{grubcpu}-%{platform}
# build efi bootloader on some platforms only:
%if ! 0%{?efi}
%global efi %{ix86} x86_64 ia64
%endif
%ifarch %{efi}
%ifarch %{ix86}
%define grubefiarch i386-efi
%else
%define grubefiarch %{_target_cpu}-efi
%endif
%endif
%if 0%{?sles_version} == 11
%define only_efi %{nil}
%define only_x86_64 %{nil}
%endif
%if 0%{?sles_version}
%global efidir SuSE
%else
%if 0%{?suse_version}
%global efidir opensuse
%endif
%endif
Version: 2.00
Release: 0
Summary: Bootloader with support for Linux, Multiboot and more
@ -106,6 +127,10 @@ Patch17: grub2-pass-corret-root-for-nfsroot.patch
Patch18: grub2-fix-locale-en.mo.gz-not-found-error-message.patch
Patch19: grub2-fix-build-error-on-flex-2.5.37.patch
Patch20: grub2-quote-messages-in-grub.cfg.patch
Patch21: grub2-secureboot-add-linuxefi.patch
Patch22: grub2-secureboot-use-linuxefi-on-uefi.patch
Patch23: grub2-secureboot-no-insmod-on-sb.patch
Patch24: grub2-secureboot-provide-linuxefi-config.patch
PreReq: perl-Bootloader
Requires: gettext-runtime
%if 0%{?suse_version} >= 1140
@ -113,10 +138,17 @@ Requires: os-prober
%endif
Requires(post): /sbin/install-info
Requires(preun):/sbin/install-info
%if ! 0%{?only_efi:1}
Requires: grub2-%{grubarch} = %{version}-%{release}
%endif
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%if 0%{?only_x86_64:1}
ExclusiveArch: x86_64
%else
ExclusiveArch: %{ix86} x86_64 ppc ppc64
%endif
%description
This is the second version of the GRUB (Grand Unified Bootloader),
@ -130,23 +162,47 @@ kernel to your existing GRUB menu. Do not replace GRUB (grub package)
with it unless you know what are you doing. Refer to README.openSUSE
file that is part of this package's documentation for more information.
%package %{grubarch}
Summary: GRUB2 for %{platform} systems
Group: System/Boot
%description %{grubarch}
The GRand Unified Bootloader (GRUB) is a highly configurable and customizable
bootloader with modular architecture. It supports rich variety of kernel formats,
file systems, computer architectures and hardware devices. This subpackage
provides support for %{platform} systems.
%ifarch %{efi}
%package efi
Summary: GRUB2 for EFI systems
Group: System/Boot
PreReq: %{name} = %{version}-%{release}
PreReq: %{name}-%{grubefiarch} = %{version}-%{release}
%description efi
The GRand Unified Bootloader (GRUB) is a highly configurable and customizable
bootloader with modular architecture. It supports rich variety of kernel formats,
file systems, computer architectures and hardware devices. This subpackage
provides compatibility to old package and install new required one.
%package %{grubefiarch}
Summary: GRUB2 for EFI systems
Group: System/Boot
%ifarch ia64 x86_64
#Package is available on ia64 and x86_64 only and not necessarily needed
Requires: efibootmgr
%endif
Requires: grub2 = %{version}-%{release}
%description efi
%description %{grubefiarch}
The GRand Unified Bootloader (GRUB) is a highly configurable and customizable
bootloader with modular architecture. It supports rich variety of kernel formats,
file systems, computer architectures and hardware devices. This subpackage
provides support for EFI systems.
%endif
%prep
@ -182,6 +238,10 @@ mv docs/grub.texi docs/grub2.texi
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
cd ..
# README.openSUSE
@ -207,17 +267,32 @@ export CFLAGS CXXFLAGS FFLAGS
--with-platform=efi \
--program-transform-name=s,grub,%{name},
make %{?_smp_mflags}
%ifarch %{ix86}
%define grubefiarch i386-efi
#TODO: add efifwsetup module
FS_MODULES="ext2 fat btrfs ext2 xfs jfs reiserfs"
CD_MODULES=" all_video boot cat chain configfile echo \
efinet ext2 font gfxmenu gfxterm gzio halt iso9660 \
jpeg minicmd normal part_apple part_msdos part_gpt \
password_pbkdf2 png reboot search search_fs_uuid \
search_fs_file search_label sleep test video"
%ifarch x86_64
CD_MODULES="${CD_MODULES} linuxefi"
%else
%define grubefiarch %{_arch}-efi
CD_MODULES="${CD_MODULES} linux"
%endif
./grub-mkimage -O %{grubefiarch} -o grub.efi -d grub-core part_gpt hfsplus fat \
ext2 btrfs normal chain boot configfile linux appleldr minicmd \
loadbios reboot halt search font gfxterm
GRUB_MODULES="${CD_MODULES} ${FS_MODULES} mdraid09 mdraid1x"
./grub-mkimage -O %{grubefiarch} -o grub.efi -p /EFI/%{efidir} \
-d grub-core ${GRUB_MODULES}
#./grub-mkimage -O %{grubefiarch} -o grub.efi -d grub-core part_gpt hfsplus fat \
# ext2 btrfs normal chain boot configfile linux appleldr minicmd \
# loadbios reboot halt search font gfxterm
cd ..
%endif
%if ! 0%{?only_efi:1}
cd grub-%{version}
autoreconf -vi
@ -246,20 +321,25 @@ export CFLAGS CXXFLAGS FFLAGS
--program-transform-name=s,grub,%{name},
make %{?_smp_mflags}
%endif
%install
%ifarch %{efi}
cd grub-efi-%{version}
make DESTDIR=$RPM_BUILD_ROOT install
install -m 755 -d $RPM_BUILD_ROOT/boot/efi/EFI/opensuse/
install -m 755 grub.efi $RPM_BUILD_ROOT/boot/efi/EFI/opensuse/grub.efi
install -m 755 -d $RPM_BUILD_ROOT/boot/efi/EFI/%{efidir}/
install -m 755 grub.efi $RPM_BUILD_ROOT/boot/efi/EFI/%{efidir}/grub.efi
cd ..
%endif
%if ! 0%{?only_efi:1}
cd grub-%{version}
make DESTDIR=$RPM_BUILD_ROOT install
%else
cd grub-efi-%{version}
%endif
# Script that makes part of grub.cfg persist across updates
install -m 755 %{SOURCE1} $RPM_BUILD_ROOT%{_sysconfdir}/grub.d/
@ -296,6 +376,7 @@ install -m 755 -D %{SOURCE6} $RPM_BUILD_ROOT%{_sbindir}/grub2-once
/sbin/install-info %{_infodir}/grub-dev.info %{_infodir}/dir || :
/sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || :
%if ! 0%{?only_efi:1}
# To check by current loader settings
if [ -f %{_sysconfdir}/sysconfig/bootloader ]; then
. %{_sysconfdir}/sysconfig/bootloader
@ -333,6 +414,8 @@ elif [ "x${LOADER_TYPE}" = "xgrub2" ]; then
# It's enought to call update-bootloader --refesh to install grub2 and update it's config
/sbin/update-bootloader --refresh || true
fi
%endif
%ifarch %{efi}
@ -406,6 +489,7 @@ if [ $1 = 0 ]; then
/sbin/install-info --delete %{_infodir}/grub-dev.info %{_infodir}/dir || :
/sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || :
%if ! 0%{?only_efi:1}
# To check by current loader settings
if [ -f %{_sysconfdir}/sysconfig/bootloader ]; then
. %{_sysconfdir}/sysconfig/bootloader
@ -433,13 +517,19 @@ if [ $1 = 0 ]; then
# we have no idea what's been installed. (And a blind remove is dangerous
# to remove user's or other package's file accidently ..)
fi
%endif
fi
%if 0%{?only_efi:1}
%define source_dir grub-efi-%{version}
%else
%define source_dir grub-%{version}
%endif
%files -f grub-%{version}/%{name}.lang
%files -f %{source_dir}/%{name}.lang
%defattr(-,root,root,-)
%doc grub-%{version}/COPYING grub-%{version}/NEWS grub-%{version}/README
%doc grub-%{version}/THANKS grub-%{version}/TODO grub-%{version}/ChangeLog
%doc grub-%{version}/README.openSUSE
%doc %{source_dir}/COPYING %{source_dir}/NEWS %{source_dir}/README
%doc %{source_dir}/THANKS %{source_dir}/TODO %{source_dir}/ChangeLog
%doc %{source_dir}/README.openSUSE
%dir /boot/%{name}
%ghost /boot/%{name}/grub.cfg
%{_sysconfdir}/bash_completion.d/grub
@ -470,22 +560,7 @@ fi
%{_bindir}/%{name}-mkstandalone
%{_bindir}/%{name}-mount
%{_bindir}/%{name}-script-check
%dir %{_libdir}/%{name}/
%dir %{_libdir}/%{name}/%{grubcpu}-%{platform}/
%ifnarch ppc ppc64
%{_libdir}/%{name}/%{grubcpu}-%{platform}/*.image
%endif
%{_libdir}/%{name}/%{grubcpu}-%{platform}/*.img
%{_libdir}/%{name}/%{grubcpu}-%{platform}/*.lst
%{_libdir}/%{name}/%{grubcpu}-%{platform}/*.mod
%{_libdir}/%{name}/%{grubcpu}-%{platform}/*.module
%ifarch x86_64
%{_libdir}/%{name}/%{grubcpu}-%{platform}/efiemu*.o
%endif
%{_libdir}/%{name}/%{grubcpu}-%{platform}/gdb_grub2
%{_libdir}/%{name}/%{grubcpu}-%{platform}/gmodule.pl
%{_libdir}/%{name}/%{grubcpu}-%{platform}/kernel.exec
%{_libdir}/%{name}/%{grubcpu}-%{platform}/modinfo.sh
%dir %{_libdir}/%{name}
%dir %{_datadir}/%{name}
%if 0%{?suse_version} >= 1140
%{_datadir}/%{name}/*.pf2
@ -494,20 +569,43 @@ fi
%{_infodir}/grub-dev.info*
%{_infodir}/%{name}.info*
%ifarch %{efi}
%if ! 0%{?only_efi:1}
%files %{grubarch}
%defattr(-,root,root,-)
%dir %{_libdir}/%{name}/%{grubarch}
%ifnarch ppc ppc64
%{_libdir}/%{name}/%{grubarch}/*.image
%endif
%{_libdir}/%{name}/%{grubarch}/*.img
%{_libdir}/%{name}/%{grubarch}/*.lst
%{_libdir}/%{name}/%{grubarch}/*.mod
%{_libdir}/%{name}/%{grubarch}/*.module
%ifarch x86_64
%{_libdir}/%{name}/%{grubarch}/efiemu*.o
%endif
%{_libdir}/%{name}/%{grubarch}/gdb_grub2
%{_libdir}/%{name}/%{grubarch}/gmodule.pl
%{_libdir}/%{name}/%{grubarch}/kernel.exec
%{_libdir}/%{name}/%{grubarch}/modinfo.sh
%endif
%ifarch %{efi}
%files efi
%defattr(-,root,root,-)
%dir /boot/efi
%dir /boot/efi/EFI
%dir /boot/efi/EFI/opensuse
%attr(0755,root,root)/boot/efi/EFI/opensuse/grub.efi
%doc %{source_dir}/README
%ghost /boot/grub2-efi
%{_sbindir}/grub2-efi-install
%{_sbindir}/grub2-efi-mkconfig
%{_sbindir}/grub2-efi-set-default
%{_bindir}/grub2-efi-editenv
%dir %{_libdir}/%{name}/%{grubefiarch}/
%files %{grubefiarch}
%defattr(-,root,root,-)
%dir /boot/efi
%dir /boot/efi/EFI
%dir /boot/efi/EFI/%{efidir}
%attr(0755,root,root)/boot/efi/EFI/%{efidir}/grub.efi
%dir %{_libdir}/%{name}/%{grubefiarch}
%{_libdir}/%{name}/%{grubefiarch}/*.img
%{_libdir}/%{name}/%{grubefiarch}/*.lst
%{_libdir}/%{name}/%{grubefiarch}/*.mod
@ -517,5 +615,3 @@ fi
%{_libdir}/%{name}/%{grubefiarch}/kernel.exec
%{_libdir}/%{name}/%{grubefiarch}/modinfo.sh
%endif
%changelog