Accepting request 150545 from Base:System

a couple of secureboot changes and some improvement.

OBS-URL: https://build.opensuse.org/request/show/150545
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/grub2?expand=0&rev=56
This commit is contained in:
Stephan Kulow 2013-01-31 13:48:08 +00:00 committed by Git OBS Bridge
parent 5c779d6686
commit 716e24f030
6 changed files with 747 additions and 21 deletions

View File

@ -9,6 +9,10 @@ GRUB_TIMEOUT=10
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash=silent"
GRUB_CMDLINE_LINUX=""
# Uncomment to automatically save last booted menu entry in GRUB2 environment
# variable `saved_entry'
#GRUB_SAVEDEFAULT="true"
# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)

50
grub2-cdpath.patch Normal file
View File

@ -0,0 +1,50 @@
From: Matthew Garrett <mjg@redhat.com>
Date: 2012-07-10 11:58:52 EDT
Subject: [PATCH] Add support for crappy cd craparino
References: fate#314485
Patch-Mainline: no
Signed-off-by: Michael Chang <mchang@suse.com>
Follow other code in this function and duplicate device path
before overwriting it.
Signed-off-by: Andrey Borzenkov <arvidjaar@gmail.com>
Index: grub-2.00/grub-core/disk/efi/efidisk.c
===================================================================
--- grub-2.00.orig/grub-core/disk/efi/efidisk.c
+++ grub-2.00/grub-core/disk/efi/efidisk.c
@@ -820,6 +820,31 @@ grub_efidisk_get_device_name (grub_efi_h
return dev_name;
}
+ else if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE &&
+ (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE))
+ {
+ grub_efi_device_path_t *dup_dp, *dup_ldp;
+
+ /* It is necessary to duplicate the device path so that GRUB
+ can overwrite it. */
+ dup_dp = duplicate_device_path (dp);
+ if (! dup_dp)
+ return 0;
+
+ dup_ldp = find_last_device_path (dup_dp);
+ dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+ dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+ dup_ldp->length[0] = 4;
+ dup_ldp->length[1] = 0;
+
+ if (!get_diskname_from_path (dup_dp, device_name))
+ {
+ grub_free (dup_dp);
+ return 0;
+ }
+ grub_free (dup_dp);
+ return grub_strdup (device_name);
+ }
else
{
/* This should be an entire disk. */

View File

@ -45,12 +45,9 @@ $grub2_dir = "";
while (<SYSCONF>) {
if (/LOADER_TYPE="(.*)"/) {
my $bl = $1;
if ($bl eq "grub2") {
if ($bl eq "grub2" || $bl eq "grub2-efi") {
$grub2_dir = "/boot/grub2";
$grub2_reboot = "/usr/sbin/grub2-reboot";
} elsif ($bl eq "grub2-efi") {
$grub2_dir = "/boot/grub2-efi";
$grub2_reboot = "/usr/sbin/grub2-efi-reboot";
}
last;
}

View File

@ -0,0 +1,646 @@
From 06ff1079788fedac5e3f1f12ed7bbe69228a7ae0 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Tue, 18 Dec 2012 16:54:03 +0800
Subject: [PATCH] Add secureboot support on efi chainloader
References: fate#314485
Patch-Mainline: no
Expand the chainloader to be able to verify the image by means of shim
lock protocol. The PE/COFF image is loaded and relocated by the
chainloader instead of calling LoadImage and StartImage UEFI boot
Service as they require positive verification result from keys enrolled
in KEK or DB. The shim will use MOK in addition to firmware enrolled
keys to verify the image.
The chainloader module could be used to load other UEFI bootloaders,
such as xen.efi, and could be signed by any of MOK, KEK or DB.
Signed-off-by: Michael Chang <mchang@suse.com>
---
grub-core/loader/efi/chainloader.c | 538 +++++++++++++++++++++++++++++++++--
1 files changed, 507 insertions(+), 31 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 3f3e6e3..12e1aff 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -36,15 +36,30 @@
#include <grub/i18n.h>
#include <grub/net.h>
+#ifdef __x86_64__
+#define SUPPORT_SECURE_BOOT
+#endif
+
+#ifdef SUPPORT_SECURE_BOOT
+#include <grub/efi/pe32.h>
+#endif
+
GRUB_MOD_LICENSE ("GPLv3+");
static grub_dl_t my_mod;
static grub_efi_physical_address_t address;
static grub_efi_uintn_t pages;
+static grub_ssize_t fsize;
static grub_efi_device_path_t *file_path;
static grub_efi_handle_t image_handle;
static grub_efi_char16_t *cmdline;
+static grub_ssize_t cmdline_len;
+
+#ifdef SUPPORT_SECURE_BOOT
+static grub_efi_boolean_t debug_secureboot = 0;
+static grub_efi_status_t (*entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table);
+#endif
static grub_err_t
grub_chainloader_unload (void)
@@ -186,12 +201,458 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
return file_path;
}
+#ifdef SUPPORT_SECURE_BOOT
+#define SHIM_LOCK_GUID \
+ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
+
+struct grub_pe32_header_no_msdos_stub
+{
+ char signature[GRUB_PE32_SIGNATURE_SIZE];
+ struct grub_pe32_coff_header coff_header;
+ struct grub_pe64_optional_header optional_header;
+};
+
+struct pe_coff_loader_image_context
+{
+ grub_efi_uint64_t image_address;
+ grub_efi_uint64_t image_size;
+ grub_efi_uint64_t entry_point;
+ grub_efi_uintn_t size_of_headers;
+ grub_efi_uint16_t image_type;
+ grub_efi_uint16_t number_of_sections;
+ struct grub_pe32_section_table *first_section;
+ struct grub_pe32_data_directory *reloc_dir;
+ struct grub_pe32_data_directory *sec_dir;
+ grub_efi_uint64_t number_of_rva_and_sizes;
+ struct grub_pe32_header_no_msdos_stub *pe_hdr;
+};
+
+typedef struct pe_coff_loader_image_context pe_coff_loader_image_context_t;
+
+struct grub_efi_shim_lock
+{
+ grub_efi_status_t (*verify)(void *buffer,
+ grub_efi_uint32_t size);
+ grub_efi_status_t (*hash)(void *data,
+ grub_efi_int32_t datasize,
+ pe_coff_loader_image_context_t *context,
+ grub_efi_uint8_t *sha256hash,
+ grub_efi_uint8_t *sha1hash);
+ grub_efi_status_t (*context)(void *data,
+ grub_efi_uint32_t size,
+ pe_coff_loader_image_context_t *context);
+};
+
+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
+
+static grub_efi_boolean_t
+grub_secure_validate (void *data, grub_efi_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)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "no shim lock protocol");
+ return 0;
+ }
+
+ if (shim_lock->verify (data, size) == GRUB_EFI_SUCCESS)
+ {
+ grub_dprintf ("chain", "verify success\n");
+ return 1;
+ }
+
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "verify failed");
+ return 0;
+}
+
+static grub_efi_boolean_t
+grub_secure_mode (void)
+{
+ grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
+ grub_uint8_t *data;
+ grub_size_t datasize;
+
+ data = grub_efi_get_variable ("SecureBoot", &efi_var_guid, &datasize);
+
+ if (data)
+ {
+ grub_dprintf ("chain", "SecureBoot: %d, datasize %d\n", (int)*data, (int)datasize);
+ }
+
+ if (data && (datasize == 1))
+ {
+ if (*data != 1)
+ {
+ grub_dprintf ("chain", "secure boot not enabled\n");
+ return 0;
+ }
+ }
+ else
+ {
+ grub_dprintf ("chain", "unknown secure boot status\n");
+ return 0;
+ }
+
+ grub_free (data);
+
+ data = grub_efi_get_variable ("SetupMode", &efi_var_guid, &datasize);
+
+ if (data)
+ {
+ grub_dprintf ("chain", "SetupMode: %d, datasize %d\n", (int)*data, (int)datasize);
+ }
+
+ if (data && (datasize == 1))
+ {
+ if (*data == 1)
+ {
+ grub_dprintf ("chain", "platform in setup mode\n");
+ return 0;
+ }
+ }
+
+ grub_free (data);
+
+ return 1;
+}
+
+static grub_efi_boolean_t
+read_header (void *data, grub_efi_uint32_t size, pe_coff_loader_image_context_t *context)
+{
+ grub_efi_guid_t guid = SHIM_LOCK_GUID;
+ grub_efi_shim_lock_t *shim_lock;
+ grub_efi_status_t status;
+
+ shim_lock = grub_efi_locate_protocol (&guid, NULL);
+
+ if (!shim_lock)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "no shim lock protocol");
+ return 0;
+ }
+
+ status = shim_lock->context (data, size, context);
+
+ if (status == GRUB_EFI_SUCCESS)
+ {
+ grub_dprintf ("chain", "context success\n");
+ return 1;
+ }
+
+ switch (status)
+ {
+ case GRUB_EFI_UNSUPPORTED:
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error unsupported");
+ break;
+ case GRUB_EFI_INVALID_PARAMETER:
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error invalid parameter");
+ break;
+ default:
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error code");
+ break;
+ }
+
+ return 0;
+}
+
+static void*
+image_address (void *image, grub_efi_uint64_t sz, grub_efi_uint64_t adr)
+{
+ if (adr > sz)
+ return NULL;
+
+ return ((grub_uint8_t*)image + adr);
+}
+
+static grub_efi_status_t
+relocate_coff (pe_coff_loader_image_context_t *context, void *data)
+{
+ struct grub_pe32_data_directory *reloc_base, *reloc_base_end;
+ grub_efi_uint64_t adjust;
+ grub_efi_uint16_t *reloc, *reloc_end;
+ char *fixup, *fixup_base, *fixup_data = NULL;
+ grub_efi_uint16_t *fixup_16;
+ grub_efi_uint32_t *fixup_32;
+ grub_efi_uint64_t *fixup_64;
+
+ grub_efi_uint64_t size = context->image_size;
+ void *image_end = (char *)data + size;
+
+ context->pe_hdr->optional_header.image_base = (grub_uint64_t)data;
+
+ if (context->number_of_rva_and_sizes <= 5 || context->reloc_dir->size == 0)
+ {
+ grub_dprintf ("chain", "no need to reloc, we are done\n");
+ return GRUB_EFI_SUCCESS;
+ }
+
+ reloc_base = image_address (data, size, context->reloc_dir->rva);
+ reloc_base_end = image_address (data, size, context->reloc_dir->rva + context->reloc_dir->size -1);
+
+ grub_dprintf ("chain", "reloc_base %p reloc_base_end %p\n", reloc_base, reloc_base_end);
+
+ if (!reloc_base || !reloc_base_end)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc table overflows binary");
+ return GRUB_EFI_UNSUPPORTED;
+ }
+
+ adjust = (grub_uint64_t)data - context->image_address;
+
+ while (reloc_base < reloc_base_end)
+ {
+ reloc = (grub_uint16_t *)((char*)reloc_base + sizeof (struct grub_pe32_data_directory));
+ reloc_end = (grub_uint16_t *)((char*)reloc_base + reloc_base->size);
+
+ if ((void *)reloc_end < data || (void *)reloc_end > image_end)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc table overflows binary");
+ return GRUB_EFI_UNSUPPORTED;
+ }
+
+ fixup_base = image_address(data, size, reloc_base->rva);
+
+ if (!fixup_base)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid fixupbase");
+ return GRUB_EFI_UNSUPPORTED;
+ }
+
+ while (reloc < reloc_end)
+ {
+ fixup = fixup_base + (*reloc & 0xFFF);
+ switch ((*reloc) >> 12)
+ {
+ case GRUB_PE32_REL_BASED_ABSOLUTE:
+ break;
+ case GRUB_PE32_REL_BASED_HIGH:
+ fixup_16 = (grub_uint16_t *)fixup;
+ *fixup_16 = (grub_uint16_t) (*fixup_16 + ((grub_uint16_t)((grub_uint32_t)adjust >> 16)));
+ if (fixup_data != NULL)
+ {
+ *(grub_uint16_t *) fixup_data = *fixup_16;
+ fixup_data = fixup_data + sizeof (grub_uint16_t);
+ }
+ break;
+ case GRUB_PE32_REL_BASED_LOW:
+ fixup_16 = (grub_uint16_t *)fixup;
+ *fixup_16 = (grub_uint16_t) (*fixup_16 + (grub_uint16_t)adjust );
+ if (fixup_data != NULL)
+ {
+ *(grub_uint16_t *) fixup_data = *fixup_16;
+ fixup_data = fixup_data + sizeof (grub_uint16_t);
+ }
+ break;
+ case GRUB_PE32_REL_BASED_HIGHLOW:
+ fixup_32 = (grub_uint32_t *)fixup;
+ *fixup_32 = *fixup_32 + (grub_uint32_t)adjust;
+ if (fixup_data != NULL)
+ {
+ fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint32_t));
+ *(grub_uint32_t *) fixup_data = *fixup_32;
+ fixup_data += sizeof (grub_uint32_t);
+ }
+ break;
+ case GRUB_PE32_REL_BASED_DIR64:
+ fixup_64 = (grub_uint64_t *)fixup;
+ *fixup_64 = *fixup_64 + (grub_uint64_t)adjust;
+ if (fixup_data != NULL)
+ {
+ fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint64_t));
+ *(grub_uint64_t *) fixup_data = *fixup_64;
+ fixup_data += sizeof (grub_uint64_t);
+ }
+ break;
+ default:
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown relocation");
+ return GRUB_EFI_UNSUPPORTED;
+ }
+ reloc += 1;
+ }
+ reloc_base = (struct grub_pe32_data_directory *)reloc_end;
+ }
+
+ return GRUB_EFI_SUCCESS;
+}
+
+static grub_efi_device_path_t *
+grub_efi_get_media_file_path (grub_efi_device_path_t *dp)
+{
+ while (1)
+ {
+ grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
+ grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
+
+ if (type == GRUB_EFI_END_DEVICE_PATH_TYPE)
+ break;
+ else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
+ && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
+ return dp;
+
+ dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
+ }
+
+ return NULL;
+}
+
+static grub_efi_boolean_t
+handle_image (void *data, grub_efi_uint32_t datasize)
+{
+ grub_efi_boot_services_t *b;
+ grub_efi_loaded_image_t *li, li_bak;
+ grub_efi_status_t efi_status;
+ char *buffer = NULL;
+ char *buffer_aligned = NULL;
+ grub_efi_uint32_t i, size;
+ struct grub_pe32_section_table *section;
+ char *base, *end;
+ pe_coff_loader_image_context_t context;
+ grub_uint32_t section_alignment;
+ grub_uint32_t buffer_size;
+
+ b = grub_efi_system_table->boot_services;
+
+ if (read_header (data, datasize, &context))
+ {
+ grub_dprintf ("chain", "Succeed to read header\n");
+ }
+ else
+ {
+ grub_dprintf ("chain", "Failed to read header\n");
+ goto error_exit;
+ }
+
+ section_alignment = context.pe_hdr->optional_header.section_alignment;
+ buffer_size = context.image_size + section_alignment;
+
+ efi_status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA,
+ buffer_size, &buffer);
+
+ if (efi_status != GRUB_EFI_SUCCESS)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ goto error_exit;
+ }
+
+ buffer_aligned = (char *)ALIGN_DOWN ((grub_addr_t)buffer, section_alignment);
+
+ grub_memcpy (buffer_aligned, data, context.size_of_headers);
+
+ section = context.first_section;
+ for (i = 0; i < context.number_of_sections; i++)
+ {
+ size = section->virtual_size;
+ if (size > section->raw_data_size)
+ size = section->raw_data_size;
+
+ base = image_address (buffer_aligned, context.image_size, section->virtual_address);
+ end = image_address (buffer_aligned, context.image_size, section->virtual_address + size - 1);
+
+ if (!base || !end)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid section size");
+ goto error_exit;
+ }
+
+ if (section->raw_data_size > 0)
+ grub_memcpy (base, (grub_efi_uint8_t*)data + section->raw_data_offset, size);
+
+ if (size < section->virtual_size)
+ grub_memset (base + size, 0, section->virtual_size - size);
+
+ grub_dprintf ("chain", "copied section %s\n", section->name);
+ section += 1;
+ }
+
+ efi_status = relocate_coff (&context, buffer_aligned);
+
+ if (efi_status != GRUB_EFI_SUCCESS)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "relocation failed");
+ goto error_exit;
+ }
+
+ entry_point = image_address (buffer_aligned, context.image_size, context.entry_point);
+
+ if (!entry_point)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid entry point");
+ goto error_exit;
+ }
+
+ li = grub_efi_get_loaded_image (grub_efi_image_handle);
+ if (!li)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "no loaded image available");
+ goto error_exit;
+ }
+
+ grub_memcpy (&li_bak, li, sizeof (grub_efi_loaded_image_t));
+ li->image_base = buffer_aligned;
+ li->image_size = context.image_size;
+ li->load_options = cmdline;
+ li->load_options_size = cmdline_len;
+ li->file_path = grub_efi_get_media_file_path (file_path);
+ if (li->file_path)
+ {
+ grub_printf ("file path: ");
+ grub_efi_print_device_path (li->file_path);
+ }
+ else
+ {
+ grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching file path found");
+ goto error_exit;
+ }
+
+ efi_status = efi_call_2 (entry_point, grub_efi_image_handle, grub_efi_system_table);
+
+ grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t));
+ efi_status = efi_call_1 (b->free_pool, buffer);
+
+ return 1;
+
+error_exit:
+ if (buffer)
+ efi_call_1 (b->free_pool, buffer);
+
+ return 0;
+
+}
+
+static grub_err_t
+grub_secureboot_chainloader_unload (void)
+{
+ grub_efi_boot_services_t *b;
+
+ b = grub_efi_system_table->boot_services;
+ efi_call_2 (b->free_pages, address, pages);
+ grub_free (file_path);
+ grub_free (cmdline);
+ cmdline = 0;
+ file_path = 0;
+
+ grub_dl_unref (my_mod);
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_secureboot_chainloader_boot (void)
+{
+ handle_image ((void *)address, fsize);
+ grub_loader_unset ();
+ return grub_errno;
+}
+#endif
+
static grub_err_t
grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
grub_file_t file = 0;
- grub_ssize_t size;
grub_efi_status_t status;
grub_efi_boot_services_t *b;
grub_device_t dev = 0;
@@ -213,6 +674,32 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
b = grub_efi_system_table->boot_services;
+ if (argc > 1)
+ {
+ int i;
+ grub_efi_char16_t *p16;
+
+ for (i = 1, cmdline_len = 0; i < argc; i++)
+ cmdline_len += grub_strlen (argv[i]) + 1;
+
+ cmdline_len *= sizeof (grub_efi_char16_t);
+ cmdline = p16 = grub_malloc (cmdline_len);
+ if (! cmdline)
+ goto fail;
+
+ for (i = 1; i < argc; i++)
+ {
+ char *p8;
+
+ p8 = argv[i];
+ while (*p8)
+ *(p16++) = *(p8++);
+
+ *(p16++) = ' ';
+ }
+ *(--p16) = 0;
+ }
+
file = grub_file_open (filename);
if (! file)
goto fail;
@@ -258,14 +745,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_printf ("file path: ");
grub_efi_print_device_path (file_path);
- size = grub_file_size (file);
- if (!size)
+ fsize = grub_file_size (file);
+ if (!fsize)
{
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
filename);
goto fail;
}
- pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12);
+ pages = (((grub_efi_uintn_t) fsize + ((1 << 12) - 1)) >> 12);
status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
GRUB_EFI_LOADER_CODE,
@@ -278,7 +765,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
- if (grub_file_read (file, (void *) ((grub_addr_t) address), size) != size)
+ if (grub_file_read (file, (void *) ((grub_addr_t) address), fsize) != fsize)
{
if (grub_errno == GRUB_ERR_NONE)
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
@@ -287,8 +774,17 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
+#ifdef SUPPORT_SECURE_BOOT
+ if (debug_secureboot || (grub_secure_mode() && grub_secure_validate ((void *)address, fsize)))
+ {
+ grub_file_close (file);
+ grub_loader_set (grub_secureboot_chainloader_boot, grub_secureboot_chainloader_unload, 0);
+ return 0;
+ }
+#endif
+
status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
- (void *) ((grub_addr_t) address), size,
+ (void *) ((grub_addr_t) address), fsize,
&image_handle);
if (status != GRUB_EFI_SUCCESS)
{
@@ -313,33 +809,10 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_file_close (file);
- if (argc > 1)
+ if (cmdline)
{
- int i, len;
- grub_efi_char16_t *p16;
-
- for (i = 1, len = 0; i < argc; i++)
- len += grub_strlen (argv[i]) + 1;
-
- len *= sizeof (grub_efi_char16_t);
- cmdline = p16 = grub_malloc (len);
- if (! cmdline)
- goto fail;
-
- for (i = 1; i < argc; i++)
- {
- char *p8;
-
- p8 = argv[i];
- while (*p8)
- *(p16++) = *(p8++);
-
- *(p16++) = ' ';
- }
- *(--p16) = 0;
-
loaded_image->load_options = cmdline;
- loaded_image->load_options_size = len;
+ loaded_image->load_options_size = cmdline_len;
}
grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
@@ -358,6 +831,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
if (address)
efi_call_2 (b->free_pages, address, pages);
+ if (cmdline)
+ grub_free (cmdline);
+
grub_dl_unref (my_mod);
return grub_errno;
--
1.7.3.4

View File

@ -1,3 +1,28 @@
-------------------------------------------------------------------
Wed Jan 30 07:29:29 UTC 2013 - mchang@suse.com
- sync from SLE-11 SP3 to date
- set empty prefix to grub.efi for looking up in current directory
- grub2-cdpath.patch: fix the grub.cfg not found when booting from
optical disk
- put grub.efi in grub2's source module directory
- create links in system's efi directory to grub.efi
- arvidjaar: do not overwrite device path in grub2-cdpath.patch
-------------------------------------------------------------------
Wed Jan 30 04:36:45 UTC 2013 - arvidjaar@gmail.com
- remove obsolete reference to /boot/grub2-efi and /usr/sbin/grub2-efi
from grub2-once
- add GRUB_SAVEDFAULT description to /etc/default/grub
-------------------------------------------------------------------
Fri Jan 18 07:39:18 UTC 2013 - mchang@suse.com
- ship a Secure Boot UEFI compatible bootloader (fate#314485)
- add grub2-secureboot-chainloader.patch, which expands the efi
chainloader to be able to verify images via shim lock protocol.
-------------------------------------------------------------------
Tue Jan 8 08:09:01 UTC 2013 - mchang@suse.com

View File

@ -81,14 +81,6 @@ BuildRequires: guile
%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
@ -135,6 +127,8 @@ Patch25: 30_os-prober_UEFI_support.patch
Patch26: grub2-fix-enumeration-of-extended-partition.patch
Patch27: grub2-add-device-to-os_prober-linux-menuentry.patch
Patch28: grub2-fix-unquoted-string-in-class.patch
Patch29: grub2-secureboot-chainloader.patch
Patch30: grub2-cdpath.patch
PreReq: perl-Bootloader
Requires: gettext-runtime
%if 0%{?suse_version} >= 1140
@ -250,6 +244,8 @@ mv docs/grub.texi docs/grub2.texi
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
cd ..
# README.openSUSE
@ -278,9 +274,9 @@ make %{?_smp_mflags}
#TODO: add efifwsetup module
FS_MODULES="ext2 fat btrfs ext2 xfs jfs reiserfs"
FS_MODULES="ext2 btrfs ext2 xfs jfs reiserfs"
CD_MODULES=" all_video boot cat chain configfile echo \
efinet ext2 font gfxmenu gfxterm gzio halt iso9660 \
efinet fat 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"
@ -292,7 +288,7 @@ CD_MODULES="${CD_MODULES} linux"
%endif
GRUB_MODULES="${CD_MODULES} ${FS_MODULES} mdraid09 mdraid1x"
./grub-mkimage -O %{grubefiarch} -o grub.efi -p /EFI/%{efidir} \
./grub-mkimage -O %{grubefiarch} -o grub.efi --prefix= \
-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 \
@ -336,8 +332,17 @@ make %{?_smp_mflags}
cd grub-efi-%{version}
make DESTDIR=$RPM_BUILD_ROOT install
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
install -m 644 grub.efi $RPM_BUILD_ROOT%{_libdir}/%{name}/%{grubefiarch}/grub.efi
# Create grub.efi link to system efi directory
# This is for tools like kiwi not fiddling with the path
%if "%{grubefiarch}" == "x86_64-efi"
%define sysefidir %{_exec_prefix}/lib64/efi
%else
%define sysefidir %{_libdir}/efi
%endif
install -d $RPM_BUILD_ROOT%{sysefidir}
ln -sf ../../../%{_libdir}/%{name}/%{grubefiarch}/grub.efi $RPM_BUILD_ROOT%{sysefidir}/grub.efi
cd ..
%endif
@ -608,11 +613,8 @@ fi
%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}/grub.efi
%{_libdir}/%{name}/%{grubefiarch}/*.img
%{_libdir}/%{name}/%{grubefiarch}/*.lst
%{_libdir}/%{name}/%{grubefiarch}/*.mod
@ -621,6 +623,8 @@ fi
%{_libdir}/%{name}/%{grubefiarch}/gmodule.pl
%{_libdir}/%{name}/%{grubefiarch}/kernel.exec
%{_libdir}/%{name}/%{grubefiarch}/modinfo.sh
%dir %{sysefidir}
%{sysefidir}/grub.efi
%endif
%changelog