bootx64.efi and grubx64.efi are signed with VMware key.
grub2 version updated to 2.02~rc2.
security hardening added to grub2-efi.
Change-Id: I148468984a3cc5ec5ba9d2bd2bdcaf7c67612b66
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/2439
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Anish Swaminathan <anishs@vmware.com>
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,661 @@ |
| 0 |
+From 0982e048621339e212fda782ed10ff1ca09eb8d2 Mon Sep 17 00:00:00 2001 |
|
| 1 |
+From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 2 |
+Date: Tue, 10 Jul 2012 11:58:52 -0400 |
|
| 3 |
+Subject: [PATCH] Secure Boot support |
|
| 4 |
+ |
|
| 5 |
+New commands: linuxefi, initrdefi |
|
| 6 |
+If running under secure boot use linuxefi loader only and linux |
|
| 7 |
+command is fallback to linuxefi. |
|
| 8 |
+Forbid dl file loading (insmod and similar) when secure boot is enabled. |
|
| 9 |
+--- |
|
| 10 |
+ grub-core/Makefile.core.def | 8 + |
|
| 11 |
+ grub-core/kern/dl.c | 21 +++ |
|
| 12 |
+ grub-core/kern/efi/efi.c | 30 +++ |
|
| 13 |
+ grub-core/kern/efi/mm.c | 32 ++++ |
|
| 14 |
+ grub-core/loader/i386/efi/linux.c | 386 ++++++++++++++++++++++++++++++++++++++ |
|
| 15 |
+ grub-core/loader/i386/linux.c | 44 +++++ |
|
| 16 |
+ include/grub/efi/efi.h | 4 + |
|
| 17 |
+ include/grub/i386/linux.h | 1 + |
|
| 18 |
+ 8 files changed, 526 insertions(+) |
|
| 19 |
+ create mode 100644 grub-core/loader/i386/efi/linux.c |
|
| 20 |
+ |
|
| 21 |
+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def |
|
| 22 |
+index 2dfa22a..68e47a7 100644 |
|
| 23 |
+--- a/grub-core/Makefile.core.def |
|
| 24 |
+@@ -1734,6 +1734,14 @@ module = {
|
|
| 25 |
+ }; |
|
| 26 |
+ |
|
| 27 |
+ module = {
|
|
| 28 |
++ name = linuxefi; |
|
| 29 |
++ efi = loader/i386/efi/linux.c; |
|
| 30 |
++ efi = lib/cmdline.c; |
|
| 31 |
++ enable = i386_efi; |
|
| 32 |
++ enable = x86_64_efi; |
|
| 33 |
++}; |
|
| 34 |
++ |
|
| 35 |
++module = {
|
|
| 36 |
+ name = chain; |
|
| 37 |
+ efi = loader/efi/chainloader.c; |
|
| 38 |
+ i386_pc = loader/i386/pc/chainloader.c; |
|
| 39 |
+diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c |
|
| 40 |
+index e394cd9..04e804d 100644 |
|
| 41 |
+--- a/grub-core/kern/dl.c |
|
| 42 |
+@@ -38,6 +38,14 @@ |
|
| 43 |
+ #define GRUB_MODULES_MACHINE_READONLY |
|
| 44 |
+ #endif |
|
| 45 |
+ |
|
| 46 |
++#ifdef GRUB_MACHINE_EMU |
|
| 47 |
++#include <sys/mman.h> |
|
| 48 |
++#endif |
|
| 49 |
++ |
|
| 50 |
++#ifdef GRUB_MACHINE_EFI |
|
| 51 |
++#include <grub/efi/efi.h> |
|
| 52 |
++#endif |
|
| 53 |
++ |
|
| 54 |
+ |
|
| 55 |
+ |
|
| 56 |
+ #pragma GCC diagnostic ignored "-Wcast-align" |
|
| 57 |
+@@ -686,6 +694,19 @@ grub_dl_load_file (const char *filename) |
|
| 58 |
+ void *core = 0; |
|
| 59 |
+ grub_dl_t mod = 0; |
|
| 60 |
+ |
|
| 61 |
++#ifdef GRUB_MACHINE_EFI |
|
| 62 |
++ if (grub_efi_secure_boot ()) |
|
| 63 |
++ {
|
|
| 64 |
++#if 0 |
|
| 65 |
++ /* This is an error, but grub2-mkconfig still generates a pile of |
|
| 66 |
++ * insmod commands, so emitting it would be mostly just obnoxious. */ |
|
| 67 |
++ grub_error (GRUB_ERR_ACCESS_DENIED, |
|
| 68 |
++ "Secure Boot forbids loading module from %s", filename); |
|
| 69 |
++#endif |
|
| 70 |
++ return 0; |
|
| 71 |
++ } |
|
| 72 |
++#endif |
|
| 73 |
++ |
|
| 74 |
+ grub_boot_time ("Loading module %s", filename);
|
|
| 75 |
+ |
|
| 76 |
+ file = grub_file_open (filename); |
|
| 77 |
+diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c |
|
| 78 |
+index d467785..270eba8 100644 |
|
| 79 |
+--- a/grub-core/kern/efi/efi.c |
|
| 80 |
+@@ -264,6 +264,36 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, |
|
| 81 |
+ return NULL; |
|
| 82 |
+ } |
|
| 83 |
+ |
|
| 84 |
++grub_efi_boolean_t |
|
| 85 |
++grub_efi_secure_boot (void) |
|
| 86 |
++{
|
|
| 87 |
++ grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; |
|
| 88 |
++ grub_size_t datasize; |
|
| 89 |
++ char *secure_boot = NULL; |
|
| 90 |
++ char *setup_mode = NULL; |
|
| 91 |
++ grub_efi_boolean_t ret = 0; |
|
| 92 |
++ |
|
| 93 |
++ secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize);
|
|
| 94 |
++ |
|
| 95 |
++ if (datasize != 1 || !secure_boot) |
|
| 96 |
++ goto out; |
|
| 97 |
++ |
|
| 98 |
++ setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize);
|
|
| 99 |
++ |
|
| 100 |
++ if (datasize != 1 || !setup_mode) |
|
| 101 |
++ goto out; |
|
| 102 |
++ |
|
| 103 |
++ if (*secure_boot && !*setup_mode) |
|
| 104 |
++ ret = 1; |
|
| 105 |
++ |
|
| 106 |
++ grub_dprintf ("secureboot", "secure_boot = %d, setup_mode = %d\n",
|
|
| 107 |
++ *secure_boot, *setup_mode); |
|
| 108 |
++ out: |
|
| 109 |
++ grub_free (secure_boot); |
|
| 110 |
++ grub_free (setup_mode); |
|
| 111 |
++ return ret; |
|
| 112 |
++} |
|
| 113 |
++ |
|
| 114 |
+ #pragma GCC diagnostic ignored "-Wcast-align" |
|
| 115 |
+ |
|
| 116 |
+ /* Search the mods section from the PE32/PE32+ image. This code uses |
|
| 117 |
+diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c |
|
| 118 |
+index 20a47aa..efb15cc 100644 |
|
| 119 |
+--- a/grub-core/kern/efi/mm.c |
|
| 120 |
+@@ -49,6 +49,38 @@ static grub_efi_uintn_t finish_desc_size; |
|
| 121 |
+ static grub_efi_uint32_t finish_desc_version; |
|
| 122 |
+ int grub_efi_is_finished = 0; |
|
| 123 |
+ |
|
| 124 |
++/* Allocate pages below a specified address */ |
|
| 125 |
++void * |
|
| 126 |
++grub_efi_allocate_pages_max (grub_efi_physical_address_t max, |
|
| 127 |
++ grub_efi_uintn_t pages) |
|
| 128 |
++{
|
|
| 129 |
++ grub_efi_status_t status; |
|
| 130 |
++ grub_efi_boot_services_t *b; |
|
| 131 |
++ grub_efi_physical_address_t address = max; |
|
| 132 |
++ |
|
| 133 |
++ if (max > 0xffffffff) |
|
| 134 |
++ return 0; |
|
| 135 |
++ |
|
| 136 |
++ b = grub_efi_system_table->boot_services; |
|
| 137 |
++ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); |
|
| 138 |
++ |
|
| 139 |
++ if (status != GRUB_EFI_SUCCESS) |
|
| 140 |
++ return 0; |
|
| 141 |
++ |
|
| 142 |
++ if (address == 0) |
|
| 143 |
++ {
|
|
| 144 |
++ /* Uggh, the address 0 was allocated... This is too annoying, |
|
| 145 |
++ so reallocate another one. */ |
|
| 146 |
++ address = max; |
|
| 147 |
++ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); |
|
| 148 |
++ grub_efi_free_pages (0, pages); |
|
| 149 |
++ if (status != GRUB_EFI_SUCCESS) |
|
| 150 |
++ return 0; |
|
| 151 |
++ } |
|
| 152 |
++ |
|
| 153 |
++ return (void *) ((grub_addr_t) address); |
|
| 154 |
++} |
|
| 155 |
++ |
|
| 156 |
+ /* Allocate pages. Return the pointer to the first of allocated pages. */ |
|
| 157 |
+ void * |
|
| 158 |
+ grub_efi_allocate_pages (grub_efi_physical_address_t address, |
|
| 159 |
+diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c |
|
| 160 |
+new file mode 100644 |
|
| 161 |
+index 0000000..6d23063 |
|
| 162 |
+--- /dev/null |
|
| 163 |
+@@ -0,0 +1,386 @@ |
|
| 164 |
++/* |
|
| 165 |
++ * GRUB -- GRand Unified Bootloader |
|
| 166 |
++ * Copyright (C) 2012 Free Software Foundation, Inc. |
|
| 167 |
++ * |
|
| 168 |
++ * GRUB is free software: you can redistribute it and/or modify |
|
| 169 |
++ * it under the terms of the GNU General Public License as published by |
|
| 170 |
++ * the Free Software Foundation, either version 3 of the License, or |
|
| 171 |
++ * (at your option) any later version. |
|
| 172 |
++ * |
|
| 173 |
++ * GRUB is distributed in the hope that it will be useful, |
|
| 174 |
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 175 |
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 176 |
++ * GNU General Public License for more details. |
|
| 177 |
++ * |
|
| 178 |
++ * You should have received a copy of the GNU General Public License |
|
| 179 |
++ * along with GRUB. If not, see <http://www.gnu.org/licenses/>. |
|
| 180 |
++ */ |
|
| 181 |
++ |
|
| 182 |
++#include <grub/loader.h> |
|
| 183 |
++#include <grub/file.h> |
|
| 184 |
++#include <grub/err.h> |
|
| 185 |
++#include <grub/misc.h> |
|
| 186 |
++#include <grub/types.h> |
|
| 187 |
++#include <grub/mm.h> |
|
| 188 |
++#include <grub/cpu/linux.h> |
|
| 189 |
++#include <grub/command.h> |
|
| 190 |
++#include <grub/i18n.h> |
|
| 191 |
++#include <grub/lib/cmdline.h> |
|
| 192 |
++#include <grub/efi/efi.h> |
|
| 193 |
++ |
|
| 194 |
++GRUB_MOD_LICENSE ("GPLv3+");
|
|
| 195 |
++ |
|
| 196 |
++static grub_dl_t my_mod; |
|
| 197 |
++static int loaded; |
|
| 198 |
++static void *kernel_mem; |
|
| 199 |
++static grub_uint64_t kernel_size; |
|
| 200 |
++static grub_uint8_t *initrd_mem; |
|
| 201 |
++static grub_uint32_t handover_offset; |
|
| 202 |
++struct linux_kernel_params *params; |
|
| 203 |
++static char *linux_cmdline; |
|
| 204 |
++ |
|
| 205 |
++#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) |
|
| 206 |
++ |
|
| 207 |
++#define SHIM_LOCK_GUID \ |
|
| 208 |
++ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
|
|
| 209 |
++ |
|
| 210 |
++struct grub_efi_shim_lock |
|
| 211 |
++{
|
|
| 212 |
++ grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size); |
|
| 213 |
++}; |
|
| 214 |
++typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; |
|
| 215 |
++ |
|
| 216 |
++static grub_efi_boolean_t |
|
| 217 |
++grub_linuxefi_secure_validate (void *data, grub_uint32_t size) |
|
| 218 |
++{
|
|
| 219 |
++ grub_efi_guid_t guid = SHIM_LOCK_GUID; |
|
| 220 |
++ grub_efi_shim_lock_t *shim_lock; |
|
| 221 |
++ grub_efi_status_t status; |
|
| 222 |
++ |
|
| 223 |
++ grub_dprintf ("linuxefi", "Locating shim protocol\n");
|
|
| 224 |
++ shim_lock = grub_efi_locate_protocol(&guid, NULL); |
|
| 225 |
++ |
|
| 226 |
++ if (!shim_lock) |
|
| 227 |
++ {
|
|
| 228 |
++ grub_dprintf ("linuxefi", "shim not available\n");
|
|
| 229 |
++ return 0; |
|
| 230 |
++ } |
|
| 231 |
++ |
|
| 232 |
++ grub_dprintf ("linuxefi", "Asking shim to verify kernel signature\n");
|
|
| 233 |
++ status = shim_lock->verify(data, size); |
|
| 234 |
++ if (status == GRUB_EFI_SUCCESS) |
|
| 235 |
++ {
|
|
| 236 |
++ grub_dprintf ("linuxefi", "Kernel signature verification passed\n");
|
|
| 237 |
++ return 1; |
|
| 238 |
++ } |
|
| 239 |
++ |
|
| 240 |
++ grub_dprintf ("linuxefi", "Kernel signature verification failed (0x%lx)\n",
|
|
| 241 |
++ (unsigned long) status); |
|
| 242 |
++ |
|
| 243 |
++ return 0; |
|
| 244 |
++} |
|
| 245 |
++ |
|
| 246 |
++typedef void(*handover_func)(void *, grub_efi_system_table_t *, struct linux_kernel_params *); |
|
| 247 |
++ |
|
| 248 |
++static grub_err_t |
|
| 249 |
++grub_linuxefi_boot (void) |
|
| 250 |
++{
|
|
| 251 |
++ handover_func hf; |
|
| 252 |
++ int offset = 0; |
|
| 253 |
++ |
|
| 254 |
++#ifdef __x86_64__ |
|
| 255 |
++ offset = 512; |
|
| 256 |
++#endif |
|
| 257 |
++ |
|
| 258 |
++ hf = (handover_func)((char *)kernel_mem + handover_offset + offset); |
|
| 259 |
++ |
|
| 260 |
++ asm volatile ("cli");
|
|
| 261 |
++ |
|
| 262 |
++ hf (grub_efi_image_handle, grub_efi_system_table, params); |
|
| 263 |
++ |
|
| 264 |
++ /* Not reached */ |
|
| 265 |
++ return GRUB_ERR_NONE; |
|
| 266 |
++} |
|
| 267 |
++ |
|
| 268 |
++static grub_err_t |
|
| 269 |
++grub_linuxefi_unload (void) |
|
| 270 |
++{
|
|
| 271 |
++ grub_dl_unref (my_mod); |
|
| 272 |
++ loaded = 0; |
|
| 273 |
++ if (initrd_mem) |
|
| 274 |
++ grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(params->ramdisk_size)); |
|
| 275 |
++ if (linux_cmdline) |
|
| 276 |
++ grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(params->cmdline_size + 1)); |
|
| 277 |
++ if (kernel_mem) |
|
| 278 |
++ grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); |
|
| 279 |
++ if (params) |
|
| 280 |
++ grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); |
|
| 281 |
++ return GRUB_ERR_NONE; |
|
| 282 |
++} |
|
| 283 |
++ |
|
| 284 |
++static grub_err_t |
|
| 285 |
++grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), |
|
| 286 |
++ int argc, char *argv[]) |
|
| 287 |
++{
|
|
| 288 |
++ grub_file_t *files = 0; |
|
| 289 |
++ int i, nfiles = 0; |
|
| 290 |
++ grub_size_t size = 0; |
|
| 291 |
++ grub_uint8_t *ptr; |
|
| 292 |
++ |
|
| 293 |
++ if (argc == 0) |
|
| 294 |
++ {
|
|
| 295 |
++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
|
| 296 |
++ goto fail; |
|
| 297 |
++ } |
|
| 298 |
++ |
|
| 299 |
++ if (!loaded) |
|
| 300 |
++ {
|
|
| 301 |
++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
|
|
| 302 |
++ goto fail; |
|
| 303 |
++ } |
|
| 304 |
++ |
|
| 305 |
++ files = grub_zalloc (argc * sizeof (files[0])); |
|
| 306 |
++ if (!files) |
|
| 307 |
++ goto fail; |
|
| 308 |
++ |
|
| 309 |
++ for (i = 0; i < argc; i++) |
|
| 310 |
++ {
|
|
| 311 |
++ grub_file_filter_disable_compression (); |
|
| 312 |
++ files[i] = grub_file_open (argv[i]); |
|
| 313 |
++ if (! files[i]) |
|
| 314 |
++ goto fail; |
|
| 315 |
++ nfiles++; |
|
| 316 |
++ size += ALIGN_UP (grub_file_size (files[i]), 4); |
|
| 317 |
++ } |
|
| 318 |
++ |
|
| 319 |
++ initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size)); |
|
| 320 |
++ |
|
| 321 |
++ if (!initrd_mem) |
|
| 322 |
++ {
|
|
| 323 |
++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd"));
|
|
| 324 |
++ goto fail; |
|
| 325 |
++ } |
|
| 326 |
++ |
|
| 327 |
++ params->ramdisk_size = size; |
|
| 328 |
++ params->ramdisk_image = (grub_uint32_t)(grub_uint64_t) initrd_mem; |
|
| 329 |
++ |
|
| 330 |
++ ptr = initrd_mem; |
|
| 331 |
++ |
|
| 332 |
++ for (i = 0; i < nfiles; i++) |
|
| 333 |
++ {
|
|
| 334 |
++ grub_ssize_t cursize = grub_file_size (files[i]); |
|
| 335 |
++ if (grub_file_read (files[i], ptr, cursize) != cursize) |
|
| 336 |
++ {
|
|
| 337 |
++ if (!grub_errno) |
|
| 338 |
++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
|
| 339 |
++ argv[i]); |
|
| 340 |
++ goto fail; |
|
| 341 |
++ } |
|
| 342 |
++ ptr += cursize; |
|
| 343 |
++ grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); |
|
| 344 |
++ ptr += ALIGN_UP_OVERHEAD (cursize, 4); |
|
| 345 |
++ } |
|
| 346 |
++ |
|
| 347 |
++ params->ramdisk_size = size; |
|
| 348 |
++ |
|
| 349 |
++ fail: |
|
| 350 |
++ for (i = 0; i < nfiles; i++) |
|
| 351 |
++ grub_file_close (files[i]); |
|
| 352 |
++ grub_free (files); |
|
| 353 |
++ |
|
| 354 |
++ if (initrd_mem && grub_errno) |
|
| 355 |
++ grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(size)); |
|
| 356 |
++ |
|
| 357 |
++ return grub_errno; |
|
| 358 |
++} |
|
| 359 |
++ |
|
| 360 |
++static grub_err_t |
|
| 361 |
++grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
|
| 362 |
++ int argc, char *argv[]) |
|
| 363 |
++{
|
|
| 364 |
++ grub_file_t file = 0; |
|
| 365 |
++ struct linux_kernel_header lh; |
|
| 366 |
++ grub_ssize_t len, start, filelen; |
|
| 367 |
++ void *kernel; |
|
| 368 |
++ grub_err_t fail_errno; |
|
| 369 |
++ |
|
| 370 |
++ grub_dl_ref (my_mod); |
|
| 371 |
++ |
|
| 372 |
++ if (argc == 0) |
|
| 373 |
++ {
|
|
| 374 |
++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
|
| 375 |
++ goto fail; |
|
| 376 |
++ } |
|
| 377 |
++ |
|
| 378 |
++ file = grub_file_open (argv[0]); |
|
| 379 |
++ if (! file) |
|
| 380 |
++ goto fail; |
|
| 381 |
++ |
|
| 382 |
++ filelen = grub_file_size (file); |
|
| 383 |
++ |
|
| 384 |
++ kernel = grub_malloc(filelen); |
|
| 385 |
++ |
|
| 386 |
++ if (!kernel) |
|
| 387 |
++ {
|
|
| 388 |
++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
|
|
| 389 |
++ goto fail; |
|
| 390 |
++ } |
|
| 391 |
++ |
|
| 392 |
++ if (grub_file_read (file, kernel, filelen) != filelen) |
|
| 393 |
++ {
|
|
| 394 |
++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]);
|
|
| 395 |
++ goto fail; |
|
| 396 |
++ } |
|
| 397 |
++ |
|
| 398 |
++ if (! grub_linuxefi_secure_validate (kernel, filelen)) |
|
| 399 |
++ {
|
|
| 400 |
++ grub_error (GRUB_ERR_ACCESS_DENIED, N_("%s has invalid signature"), argv[0]);
|
|
| 401 |
++ grub_free (kernel); |
|
| 402 |
++ goto fail; |
|
| 403 |
++ } |
|
| 404 |
++ |
|
| 405 |
++ grub_file_seek (file, 0); |
|
| 406 |
++ |
|
| 407 |
++ grub_free(kernel); |
|
| 408 |
++ |
|
| 409 |
++ params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); |
|
| 410 |
++ |
|
| 411 |
++ if (! params) |
|
| 412 |
++ {
|
|
| 413 |
++ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); |
|
| 414 |
++ goto fail; |
|
| 415 |
++ } |
|
| 416 |
++ |
|
| 417 |
++ memset (params, 0, 16384); |
|
| 418 |
++ |
|
| 419 |
++ if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) |
|
| 420 |
++ {
|
|
| 421 |
++ if (!grub_errno) |
|
| 422 |
++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
|
| 423 |
++ argv[0]); |
|
| 424 |
++ goto fail; |
|
| 425 |
++ } |
|
| 426 |
++ |
|
| 427 |
++ if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) |
|
| 428 |
++ {
|
|
| 429 |
++ grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number"));
|
|
| 430 |
++ goto fail; |
|
| 431 |
++ } |
|
| 432 |
++ |
|
| 433 |
++ if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) |
|
| 434 |
++ {
|
|
| 435 |
++ grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors"));
|
|
| 436 |
++ goto fail; |
|
| 437 |
++ } |
|
| 438 |
++ |
|
| 439 |
++ if (lh.version < grub_cpu_to_le16 (0x020b)) |
|
| 440 |
++ {
|
|
| 441 |
++ grub_error (GRUB_ERR_BAD_OS, N_("kernel too old"));
|
|
| 442 |
++ goto fail; |
|
| 443 |
++ } |
|
| 444 |
++ |
|
| 445 |
++ if (!lh.handover_offset) |
|
| 446 |
++ {
|
|
| 447 |
++ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover"));
|
|
| 448 |
++ goto fail; |
|
| 449 |
++ } |
|
| 450 |
++ |
|
| 451 |
++ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, |
|
| 452 |
++ BYTES_TO_PAGES(lh.cmdline_size + 1)); |
|
| 453 |
++ |
|
| 454 |
++ if (!linux_cmdline) |
|
| 455 |
++ {
|
|
| 456 |
++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline"));
|
|
| 457 |
++ goto fail; |
|
| 458 |
++ } |
|
| 459 |
++ |
|
| 460 |
++ grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); |
|
| 461 |
++ grub_create_loader_cmdline (argc, argv, |
|
| 462 |
++ linux_cmdline + sizeof (LINUX_IMAGE) - 1, |
|
| 463 |
++ lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1)); |
|
| 464 |
++ |
|
| 465 |
++ lh.cmd_line_ptr = (grub_uint32_t)(grub_uint64_t)linux_cmdline; |
|
| 466 |
++ |
|
| 467 |
++ handover_offset = lh.handover_offset; |
|
| 468 |
++ |
|
| 469 |
++ start = (lh.setup_sects + 1) * 512; |
|
| 470 |
++ len = grub_file_size(file) - start; |
|
| 471 |
++ |
|
| 472 |
++ kernel_mem = grub_efi_allocate_pages(lh.pref_address, |
|
| 473 |
++ BYTES_TO_PAGES(lh.init_size)); |
|
| 474 |
++ |
|
| 475 |
++ if (!kernel_mem) |
|
| 476 |
++ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, |
|
| 477 |
++ BYTES_TO_PAGES(lh.init_size)); |
|
| 478 |
++ |
|
| 479 |
++ if (!kernel_mem) |
|
| 480 |
++ {
|
|
| 481 |
++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel"));
|
|
| 482 |
++ goto fail; |
|
| 483 |
++ } |
|
| 484 |
++ |
|
| 485 |
++ if (grub_file_seek (file, start) == (grub_off_t) -1) |
|
| 486 |
++ {
|
|
| 487 |
++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
|
| 488 |
++ argv[0]); |
|
| 489 |
++ goto fail; |
|
| 490 |
++ } |
|
| 491 |
++ |
|
| 492 |
++ if (grub_file_read (file, kernel_mem, len) != len && !grub_errno) |
|
| 493 |
++ {
|
|
| 494 |
++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
|
| 495 |
++ argv[0]); |
|
| 496 |
++ } |
|
| 497 |
++ |
|
| 498 |
++ if (grub_errno == GRUB_ERR_NONE) |
|
| 499 |
++ {
|
|
| 500 |
++ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); |
|
| 501 |
++ loaded = 1; |
|
| 502 |
++ lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; |
|
| 503 |
++ } |
|
| 504 |
++ |
|
| 505 |
++ memcpy(params, &lh, 2 * 512); |
|
| 506 |
++ |
|
| 507 |
++ params->type_of_loader = 0x21; |
|
| 508 |
++ |
|
| 509 |
++ fail: |
|
| 510 |
++ fail_errno = grub_errno; |
|
| 511 |
++ if (file) |
|
| 512 |
++ grub_file_close (file); |
|
| 513 |
++ |
|
| 514 |
++ if (fail_errno != GRUB_ERR_NONE) |
|
| 515 |
++ {
|
|
| 516 |
++ grub_dl_unref (my_mod); |
|
| 517 |
++ loaded = 0; |
|
| 518 |
++ } |
|
| 519 |
++ |
|
| 520 |
++ if (linux_cmdline && !loaded) |
|
| 521 |
++ grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1)); |
|
| 522 |
++ |
|
| 523 |
++ if (kernel_mem && !loaded) |
|
| 524 |
++ grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); |
|
| 525 |
++ |
|
| 526 |
++ if (params && !loaded) |
|
| 527 |
++ grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); |
|
| 528 |
++ |
|
| 529 |
++ return fail_errno; |
|
| 530 |
++} |
|
| 531 |
++ |
|
| 532 |
++static grub_command_t cmd_linux, cmd_initrd; |
|
| 533 |
++ |
|
| 534 |
++GRUB_MOD_INIT(linuxefi) |
|
| 535 |
++{
|
|
| 536 |
++ cmd_linux = |
|
| 537 |
++ grub_register_command ("linuxefi", grub_cmd_linux,
|
|
| 538 |
++ 0, N_("Load Linux."));
|
|
| 539 |
++ cmd_initrd = |
|
| 540 |
++ grub_register_command ("initrdefi", grub_cmd_initrd,
|
|
| 541 |
++ 0, N_("Load initrd."));
|
|
| 542 |
++ my_mod = mod; |
|
| 543 |
++} |
|
| 544 |
++ |
|
| 545 |
++GRUB_MOD_FINI(linuxefi) |
|
| 546 |
++{
|
|
| 547 |
++ grub_unregister_command (cmd_linux); |
|
| 548 |
++ grub_unregister_command (cmd_initrd); |
|
| 549 |
++} |
|
| 550 |
+diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c |
|
| 551 |
+index b15b8cc..845a5c9 100644 |
|
| 552 |
+--- a/grub-core/loader/i386/linux.c |
|
| 553 |
+@@ -75,6 +75,8 @@ static grub_size_t maximal_cmdline_size; |
|
| 554 |
+ static struct linux_kernel_params linux_params; |
|
| 555 |
+ static char *linux_cmdline; |
|
| 556 |
+ #ifdef GRUB_MACHINE_EFI |
|
| 557 |
++static int using_linuxefi; |
|
| 558 |
++static grub_command_t initrdefi_cmd; |
|
| 559 |
+ static grub_efi_uintn_t efi_mmap_size; |
|
| 560 |
+ #else |
|
| 561 |
+ static const grub_size_t efi_mmap_size = 0; |
|
| 562 |
+@@ -689,6 +691,42 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
|
| 563 |
+ |
|
| 564 |
+ grub_dl_ref (my_mod); |
|
| 565 |
+ |
|
| 566 |
++#ifdef GRUB_MACHINE_EFI |
|
| 567 |
++ using_linuxefi = 0; |
|
| 568 |
++ if (grub_efi_secure_boot ()) |
|
| 569 |
++ {
|
|
| 570 |
++ /* Try linuxefi first, which will require a successful signature check |
|
| 571 |
++ and then hand over to the kernel without calling ExitBootServices. |
|
| 572 |
++ If that fails, however, fall back to calling ExitBootServices |
|
| 573 |
++ ourselves and then booting an unsigned kernel. */ |
|
| 574 |
++ grub_dl_t mod; |
|
| 575 |
++ grub_command_t linuxefi_cmd; |
|
| 576 |
++ |
|
| 577 |
++ grub_dprintf ("linux", "Secure Boot enabled: trying linuxefi\n");
|
|
| 578 |
++ |
|
| 579 |
++ mod = grub_dl_load ("linuxefi");
|
|
| 580 |
++ if (mod) |
|
| 581 |
++ {
|
|
| 582 |
++ grub_dl_ref (mod); |
|
| 583 |
++ linuxefi_cmd = grub_command_find ("linuxefi");
|
|
| 584 |
++ initrdefi_cmd = grub_command_find ("initrdefi");
|
|
| 585 |
++ if (linuxefi_cmd && initrdefi_cmd) |
|
| 586 |
++ {
|
|
| 587 |
++ (linuxefi_cmd->func) (linuxefi_cmd, argc, argv); |
|
| 588 |
++ if (grub_errno == GRUB_ERR_NONE) |
|
| 589 |
++ {
|
|
| 590 |
++ grub_dprintf ("linux", "Handing off to linuxefi\n");
|
|
| 591 |
++ using_linuxefi = 1; |
|
| 592 |
++ return GRUB_ERR_NONE; |
|
| 593 |
++ } |
|
| 594 |
++ grub_dprintf ("linux", "linuxefi failed (%d)\n", grub_errno);
|
|
| 595 |
++ grub_errno = GRUB_ERR_ACCESS_DENIED; |
|
| 596 |
++ } |
|
| 597 |
++ } |
|
| 598 |
++ goto fail; |
|
| 599 |
++ } |
|
| 600 |
++#endif |
|
| 601 |
++ |
|
| 602 |
+ if (argc == 0) |
|
| 603 |
+ {
|
|
| 604 |
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
|
| 605 |
+@@ -1051,6 +1089,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), |
|
| 606 |
+ grub_err_t err; |
|
| 607 |
+ struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
|
|
| 608 |
+ |
|
| 609 |
++#ifdef GRUB_MACHINE_EFI |
|
| 610 |
++ /* If we're using linuxefi, just forward to initrdefi. */ |
|
| 611 |
++ if (using_linuxefi && initrdefi_cmd) |
|
| 612 |
++ return (initrdefi_cmd->func) (initrdefi_cmd, argc, argv); |
|
| 613 |
++#endif |
|
| 614 |
++ |
|
| 615 |
+ if (argc == 0) |
|
| 616 |
+ {
|
|
| 617 |
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
|
| 618 |
+diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h |
|
| 619 |
+index e9c601f..62a3d97 100644 |
|
| 620 |
+--- a/include/grub/efi/efi.h |
|
| 621 |
+@@ -40,6 +40,9 @@ void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds); |
|
| 622 |
+ void * |
|
| 623 |
+ EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address, |
|
| 624 |
+ grub_efi_uintn_t pages); |
|
| 625 |
++void * |
|
| 626 |
++EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max, |
|
| 627 |
++ grub_efi_uintn_t pages); |
|
| 628 |
+ void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, |
|
| 629 |
+ grub_efi_uintn_t pages); |
|
| 630 |
+ int |
|
| 631 |
+@@ -73,6 +76,7 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var, |
|
| 632 |
+ const grub_efi_guid_t *guid, |
|
| 633 |
+ void *data, |
|
| 634 |
+ grub_size_t datasize); |
|
| 635 |
++grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void); |
|
| 636 |
+ int |
|
| 637 |
+ EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, |
|
| 638 |
+ const grub_efi_device_path_t *dp2); |
|
| 639 |
+diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h |
|
| 640 |
+index da0ca3b..fc36bda 100644 |
|
| 641 |
+--- a/include/grub/i386/linux.h |
|
| 642 |
+@@ -139,6 +139,7 @@ struct linux_kernel_header |
|
| 643 |
+ grub_uint64_t setup_data; |
|
| 644 |
+ grub_uint64_t pref_address; |
|
| 645 |
+ grub_uint32_t init_size; |
|
| 646 |
++ grub_uint32_t handover_offset; |
|
| 647 |
+ } GRUB_PACKED; |
|
| 648 |
+ |
|
| 649 |
+ /* Boot parameters for Linux based on 2.6.12. This is used by the setup |
|
| 650 |
+-- |
|
| 651 |
+2.8.1 |
|
| 652 |
+ |
| 0 | 653 |
deleted file mode 100644 |
| ... | ... |
@@ -1,482 +0,0 @@ |
| 1 |
-From a64179016df64b72cc956fd6085ca3ed1a41baac Mon Sep 17 00:00:00 2001 |
|
| 2 |
-From: Matthew Garrett <mjg@redhat.com> |
|
| 3 |
-Date: Tue, 10 Jul 2012 11:58:52 -0400 |
|
| 4 |
-Subject: [PATCH 20/90] Add support for linuxefi |
|
| 5 |
- |
|
| 6 |
- grub-core/Makefile.core.def | 8 + |
|
| 7 |
- grub-core/kern/efi/mm.c | 32 ++++ |
|
| 8 |
- grub-core/loader/i386/efi/linux.c | 371 ++++++++++++++++++++++++++++++++++++++ |
|
| 9 |
- include/grub/efi/efi.h | 3 + |
|
| 10 |
- include/grub/i386/linux.h | 1 + |
|
| 11 |
- 5 files changed, 415 insertions(+) |
|
| 12 |
- create mode 100644 grub-core/loader/i386/efi/linux.c |
|
| 13 |
- |
|
| 14 |
-diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def |
|
| 15 |
-index f8d4634..de8c9df 100644 |
|
| 16 |
-+++ b/grub-core/Makefile.core.def |
|
| 17 |
-@@ -1732,6 +1732,14 @@ module = {
|
|
| 18 |
- }; |
|
| 19 |
- |
|
| 20 |
- module = {
|
|
| 21 |
-+ name = linuxefi; |
|
| 22 |
-+ efi = loader/i386/efi/linux.c; |
|
| 23 |
-+ efi = lib/cmdline.c; |
|
| 24 |
-+ enable = i386_efi; |
|
| 25 |
-+ enable = x86_64_efi; |
|
| 26 |
-+}; |
|
| 27 |
-+ |
|
| 28 |
-+module = {
|
|
| 29 |
- name = chain; |
|
| 30 |
- efi = loader/efi/chainloader.c; |
|
| 31 |
- i386_pc = loader/i386/pc/chainloader.c; |
|
| 32 |
-diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c |
|
| 33 |
-index 20a47aa..efb15cc 100644 |
|
| 34 |
-+++ b/grub-core/kern/efi/mm.c |
|
| 35 |
-@@ -49,6 +49,38 @@ static grub_efi_uintn_t finish_desc_size; |
|
| 36 |
- static grub_efi_uint32_t finish_desc_version; |
|
| 37 |
- int grub_efi_is_finished = 0; |
|
| 38 |
- |
|
| 39 |
-+/* Allocate pages below a specified address */ |
|
| 40 |
-+void * |
|
| 41 |
-+grub_efi_allocate_pages_max (grub_efi_physical_address_t max, |
|
| 42 |
-+ grub_efi_uintn_t pages) |
|
| 43 |
-+{
|
|
| 44 |
-+ grub_efi_status_t status; |
|
| 45 |
-+ grub_efi_boot_services_t *b; |
|
| 46 |
-+ grub_efi_physical_address_t address = max; |
|
| 47 |
-+ |
|
| 48 |
-+ if (max > 0xffffffff) |
|
| 49 |
-+ return 0; |
|
| 50 |
-+ |
|
| 51 |
-+ b = grub_efi_system_table->boot_services; |
|
| 52 |
-+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); |
|
| 53 |
-+ |
|
| 54 |
-+ if (status != GRUB_EFI_SUCCESS) |
|
| 55 |
-+ return 0; |
|
| 56 |
-+ |
|
| 57 |
-+ if (address == 0) |
|
| 58 |
-+ {
|
|
| 59 |
-+ /* Uggh, the address 0 was allocated... This is too annoying, |
|
| 60 |
-+ so reallocate another one. */ |
|
| 61 |
-+ address = max; |
|
| 62 |
-+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); |
|
| 63 |
-+ grub_efi_free_pages (0, pages); |
|
| 64 |
-+ if (status != GRUB_EFI_SUCCESS) |
|
| 65 |
-+ return 0; |
|
| 66 |
-+ } |
|
| 67 |
-+ |
|
| 68 |
-+ return (void *) ((grub_addr_t) address); |
|
| 69 |
-+} |
|
| 70 |
-+ |
|
| 71 |
- /* Allocate pages. Return the pointer to the first of allocated pages. */ |
|
| 72 |
- void * |
|
| 73 |
- grub_efi_allocate_pages (grub_efi_physical_address_t address, |
|
| 74 |
-diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c |
|
| 75 |
-new file mode 100644 |
|
| 76 |
-index 0000000..b79e632 |
|
| 77 |
-+++ b/grub-core/loader/i386/efi/linux.c |
|
| 78 |
-@@ -0,0 +1,371 @@ |
|
| 79 |
-+/* |
|
| 80 |
-+ * GRUB -- GRand Unified Bootloader |
|
| 81 |
-+ * Copyright (C) 2012 Free Software Foundation, Inc. |
|
| 82 |
-+ * |
|
| 83 |
-+ * GRUB is free software: you can redistribute it and/or modify |
|
| 84 |
-+ * it under the terms of the GNU General Public License as published by |
|
| 85 |
-+ * the Free Software Foundation, either version 3 of the License, or |
|
| 86 |
-+ * (at your option) any later version. |
|
| 87 |
-+ * |
|
| 88 |
-+ * GRUB is distributed in the hope that it will be useful, |
|
| 89 |
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 90 |
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 91 |
-+ * GNU General Public License for more details. |
|
| 92 |
-+ * |
|
| 93 |
-+ * You should have received a copy of the GNU General Public License |
|
| 94 |
-+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>. |
|
| 95 |
-+ */ |
|
| 96 |
-+ |
|
| 97 |
-+#include <grub/loader.h> |
|
| 98 |
-+#include <grub/file.h> |
|
| 99 |
-+#include <grub/err.h> |
|
| 100 |
-+#include <grub/types.h> |
|
| 101 |
-+#include <grub/mm.h> |
|
| 102 |
-+#include <grub/cpu/linux.h> |
|
| 103 |
-+#include <grub/command.h> |
|
| 104 |
-+#include <grub/i18n.h> |
|
| 105 |
-+#include <grub/lib/cmdline.h> |
|
| 106 |
-+#include <grub/efi/efi.h> |
|
| 107 |
-+ |
|
| 108 |
-+GRUB_MOD_LICENSE ("GPLv3+");
|
|
| 109 |
-+ |
|
| 110 |
-+static grub_dl_t my_mod; |
|
| 111 |
-+static int loaded; |
|
| 112 |
-+static void *kernel_mem; |
|
| 113 |
-+static grub_uint64_t kernel_size; |
|
| 114 |
-+static grub_uint8_t *initrd_mem; |
|
| 115 |
-+static grub_uint32_t handover_offset; |
|
| 116 |
-+struct linux_kernel_params *params; |
|
| 117 |
-+static char *linux_cmdline; |
|
| 118 |
-+ |
|
| 119 |
-+#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) |
|
| 120 |
-+ |
|
| 121 |
-+#define SHIM_LOCK_GUID \ |
|
| 122 |
-+ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
|
|
| 123 |
-+ |
|
| 124 |
-+struct grub_efi_shim_lock |
|
| 125 |
-+{
|
|
| 126 |
-+ grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size); |
|
| 127 |
-+}; |
|
| 128 |
-+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; |
|
| 129 |
-+ |
|
| 130 |
-+static grub_efi_boolean_t |
|
| 131 |
-+grub_linuxefi_secure_validate (void *data, grub_uint32_t size) |
|
| 132 |
-+{
|
|
| 133 |
-+ grub_efi_guid_t guid = SHIM_LOCK_GUID; |
|
| 134 |
-+ grub_efi_shim_lock_t *shim_lock; |
|
| 135 |
-+ |
|
| 136 |
-+ shim_lock = grub_efi_locate_protocol(&guid, NULL); |
|
| 137 |
-+ |
|
| 138 |
-+ if (!shim_lock) |
|
| 139 |
-+ return 1; |
|
| 140 |
-+ |
|
| 141 |
-+ if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS) |
|
| 142 |
-+ return 1; |
|
| 143 |
-+ |
|
| 144 |
-+ return 0; |
|
| 145 |
-+} |
|
| 146 |
-+ |
|
| 147 |
-+typedef void(*handover_func)(void *, grub_efi_system_table_t *, struct linux_kernel_params *); |
|
| 148 |
-+ |
|
| 149 |
-+static grub_err_t |
|
| 150 |
-+grub_linuxefi_boot (void) |
|
| 151 |
-+{
|
|
| 152 |
-+ handover_func hf; |
|
| 153 |
-+ int offset = 0; |
|
| 154 |
-+ |
|
| 155 |
-+#ifdef __x86_64__ |
|
| 156 |
-+ offset = 512; |
|
| 157 |
-+#endif |
|
| 158 |
-+ |
|
| 159 |
-+ hf = (handover_func)((char *)kernel_mem + handover_offset + offset); |
|
| 160 |
-+ |
|
| 161 |
-+ asm volatile ("cli");
|
|
| 162 |
-+ |
|
| 163 |
-+ hf (grub_efi_image_handle, grub_efi_system_table, params); |
|
| 164 |
-+ |
|
| 165 |
-+ /* Not reached */ |
|
| 166 |
-+ return GRUB_ERR_NONE; |
|
| 167 |
-+} |
|
| 168 |
-+ |
|
| 169 |
-+static grub_err_t |
|
| 170 |
-+grub_linuxefi_unload (void) |
|
| 171 |
-+{
|
|
| 172 |
-+ grub_dl_unref (my_mod); |
|
| 173 |
-+ loaded = 0; |
|
| 174 |
-+ if (initrd_mem) |
|
| 175 |
-+ grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(params->ramdisk_size)); |
|
| 176 |
-+ if (linux_cmdline) |
|
| 177 |
-+ grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(params->cmdline_size + 1)); |
|
| 178 |
-+ if (kernel_mem) |
|
| 179 |
-+ grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); |
|
| 180 |
-+ if (params) |
|
| 181 |
-+ grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); |
|
| 182 |
-+ return GRUB_ERR_NONE; |
|
| 183 |
-+} |
|
| 184 |
-+ |
|
| 185 |
-+static grub_err_t |
|
| 186 |
-+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), |
|
| 187 |
-+ int argc, char *argv[]) |
|
| 188 |
-+{
|
|
| 189 |
-+ grub_file_t *files = 0; |
|
| 190 |
-+ int i, nfiles = 0; |
|
| 191 |
-+ grub_size_t size = 0; |
|
| 192 |
-+ grub_uint8_t *ptr; |
|
| 193 |
-+ |
|
| 194 |
-+ if (argc == 0) |
|
| 195 |
-+ {
|
|
| 196 |
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
|
| 197 |
-+ goto fail; |
|
| 198 |
-+ } |
|
| 199 |
-+ |
|
| 200 |
-+ if (!loaded) |
|
| 201 |
-+ {
|
|
| 202 |
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
|
|
| 203 |
-+ goto fail; |
|
| 204 |
-+ } |
|
| 205 |
-+ |
|
| 206 |
-+ files = grub_zalloc (argc * sizeof (files[0])); |
|
| 207 |
-+ if (!files) |
|
| 208 |
-+ goto fail; |
|
| 209 |
-+ |
|
| 210 |
-+ for (i = 0; i < argc; i++) |
|
| 211 |
-+ {
|
|
| 212 |
-+ grub_file_filter_disable_compression (); |
|
| 213 |
-+ files[i] = grub_file_open (argv[i]); |
|
| 214 |
-+ if (! files[i]) |
|
| 215 |
-+ goto fail; |
|
| 216 |
-+ nfiles++; |
|
| 217 |
-+ size += ALIGN_UP (grub_file_size (files[i]), 4); |
|
| 218 |
-+ } |
|
| 219 |
-+ |
|
| 220 |
-+ initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size)); |
|
| 221 |
-+ |
|
| 222 |
-+ if (!initrd_mem) |
|
| 223 |
-+ {
|
|
| 224 |
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd"));
|
|
| 225 |
-+ goto fail; |
|
| 226 |
-+ } |
|
| 227 |
-+ |
|
| 228 |
-+ params->ramdisk_size = size; |
|
| 229 |
-+ params->ramdisk_image = (grub_uint32_t)(grub_uint64_t) initrd_mem; |
|
| 230 |
-+ |
|
| 231 |
-+ ptr = initrd_mem; |
|
| 232 |
-+ |
|
| 233 |
-+ for (i = 0; i < nfiles; i++) |
|
| 234 |
-+ {
|
|
| 235 |
-+ grub_ssize_t cursize = grub_file_size (files[i]); |
|
| 236 |
-+ if (grub_file_read (files[i], ptr, cursize) != cursize) |
|
| 237 |
-+ {
|
|
| 238 |
-+ if (!grub_errno) |
|
| 239 |
-+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
|
| 240 |
-+ argv[i]); |
|
| 241 |
-+ goto fail; |
|
| 242 |
-+ } |
|
| 243 |
-+ ptr += cursize; |
|
| 244 |
-+ grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); |
|
| 245 |
-+ ptr += ALIGN_UP_OVERHEAD (cursize, 4); |
|
| 246 |
-+ } |
|
| 247 |
-+ |
|
| 248 |
-+ params->ramdisk_size = size; |
|
| 249 |
-+ |
|
| 250 |
-+ fail: |
|
| 251 |
-+ for (i = 0; i < nfiles; i++) |
|
| 252 |
-+ grub_file_close (files[i]); |
|
| 253 |
-+ grub_free (files); |
|
| 254 |
-+ |
|
| 255 |
-+ if (initrd_mem && grub_errno) |
|
| 256 |
-+ grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(size)); |
|
| 257 |
-+ |
|
| 258 |
-+ return grub_errno; |
|
| 259 |
-+} |
|
| 260 |
-+ |
|
| 261 |
-+static grub_err_t |
|
| 262 |
-+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
|
| 263 |
-+ int argc, char *argv[]) |
|
| 264 |
-+{
|
|
| 265 |
-+ grub_file_t file = 0; |
|
| 266 |
-+ struct linux_kernel_header lh; |
|
| 267 |
-+ grub_ssize_t len, start, filelen; |
|
| 268 |
-+ void *kernel; |
|
| 269 |
-+ |
|
| 270 |
-+ grub_dl_ref (my_mod); |
|
| 271 |
-+ |
|
| 272 |
-+ if (argc == 0) |
|
| 273 |
-+ {
|
|
| 274 |
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
|
| 275 |
-+ goto fail; |
|
| 276 |
-+ } |
|
| 277 |
-+ |
|
| 278 |
-+ file = grub_file_open (argv[0]); |
|
| 279 |
-+ if (! file) |
|
| 280 |
-+ goto fail; |
|
| 281 |
-+ |
|
| 282 |
-+ filelen = grub_file_size (file); |
|
| 283 |
-+ |
|
| 284 |
-+ kernel = grub_malloc(filelen); |
|
| 285 |
-+ |
|
| 286 |
-+ if (!kernel) |
|
| 287 |
-+ {
|
|
| 288 |
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
|
|
| 289 |
-+ goto fail; |
|
| 290 |
-+ } |
|
| 291 |
-+ |
|
| 292 |
-+ if (grub_file_read (file, kernel, filelen) != filelen) |
|
| 293 |
-+ {
|
|
| 294 |
-+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]);
|
|
| 295 |
-+ goto fail; |
|
| 296 |
-+ } |
|
| 297 |
-+ |
|
| 298 |
-+ if (! grub_linuxefi_secure_validate (kernel, filelen)) |
|
| 299 |
-+ {
|
|
| 300 |
-+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
|
|
| 301 |
-+ grub_free (kernel); |
|
| 302 |
-+ goto fail; |
|
| 303 |
-+ } |
|
| 304 |
-+ |
|
| 305 |
-+ grub_file_seek (file, 0); |
|
| 306 |
-+ |
|
| 307 |
-+ grub_free(kernel); |
|
| 308 |
-+ |
|
| 309 |
-+ params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); |
|
| 310 |
-+ |
|
| 311 |
-+ if (! params) |
|
| 312 |
-+ {
|
|
| 313 |
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); |
|
| 314 |
-+ goto fail; |
|
| 315 |
-+ } |
|
| 316 |
-+ |
|
| 317 |
-+ memset (params, 0, 16384); |
|
| 318 |
-+ |
|
| 319 |
-+ if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) |
|
| 320 |
-+ {
|
|
| 321 |
-+ if (!grub_errno) |
|
| 322 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
|
| 323 |
-+ argv[0]); |
|
| 324 |
-+ goto fail; |
|
| 325 |
-+ } |
|
| 326 |
-+ |
|
| 327 |
-+ if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) |
|
| 328 |
-+ {
|
|
| 329 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number"));
|
|
| 330 |
-+ goto fail; |
|
| 331 |
-+ } |
|
| 332 |
-+ |
|
| 333 |
-+ if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) |
|
| 334 |
-+ {
|
|
| 335 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors"));
|
|
| 336 |
-+ goto fail; |
|
| 337 |
-+ } |
|
| 338 |
-+ |
|
| 339 |
-+ if (lh.version < grub_cpu_to_le16 (0x020b)) |
|
| 340 |
-+ {
|
|
| 341 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("kernel too old"));
|
|
| 342 |
-+ goto fail; |
|
| 343 |
-+ } |
|
| 344 |
-+ |
|
| 345 |
-+ if (!lh.handover_offset) |
|
| 346 |
-+ {
|
|
| 347 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover"));
|
|
| 348 |
-+ goto fail; |
|
| 349 |
-+ } |
|
| 350 |
-+ |
|
| 351 |
-+ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, |
|
| 352 |
-+ BYTES_TO_PAGES(lh.cmdline_size + 1)); |
|
| 353 |
-+ |
|
| 354 |
-+ if (!linux_cmdline) |
|
| 355 |
-+ {
|
|
| 356 |
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline"));
|
|
| 357 |
-+ goto fail; |
|
| 358 |
-+ } |
|
| 359 |
-+ |
|
| 360 |
-+ grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); |
|
| 361 |
-+ grub_create_loader_cmdline (argc, argv, |
|
| 362 |
-+ linux_cmdline + sizeof (LINUX_IMAGE) - 1, |
|
| 363 |
-+ lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1)); |
|
| 364 |
-+ |
|
| 365 |
-+ lh.cmd_line_ptr = (grub_uint32_t)(grub_uint64_t)linux_cmdline; |
|
| 366 |
-+ |
|
| 367 |
-+ handover_offset = lh.handover_offset; |
|
| 368 |
-+ |
|
| 369 |
-+ start = (lh.setup_sects + 1) * 512; |
|
| 370 |
-+ len = grub_file_size(file) - start; |
|
| 371 |
-+ |
|
| 372 |
-+ kernel_mem = grub_efi_allocate_pages(lh.pref_address, |
|
| 373 |
-+ BYTES_TO_PAGES(lh.init_size)); |
|
| 374 |
-+ |
|
| 375 |
-+ if (!kernel_mem) |
|
| 376 |
-+ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, |
|
| 377 |
-+ BYTES_TO_PAGES(lh.init_size)); |
|
| 378 |
-+ |
|
| 379 |
-+ if (!kernel_mem) |
|
| 380 |
-+ {
|
|
| 381 |
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel"));
|
|
| 382 |
-+ goto fail; |
|
| 383 |
-+ } |
|
| 384 |
-+ |
|
| 385 |
-+ if (grub_file_seek (file, start) == (grub_off_t) -1) |
|
| 386 |
-+ {
|
|
| 387 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
|
| 388 |
-+ argv[0]); |
|
| 389 |
-+ goto fail; |
|
| 390 |
-+ } |
|
| 391 |
-+ |
|
| 392 |
-+ if (grub_file_read (file, kernel_mem, len) != len && !grub_errno) |
|
| 393 |
-+ {
|
|
| 394 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
|
| 395 |
-+ argv[0]); |
|
| 396 |
-+ } |
|
| 397 |
-+ |
|
| 398 |
-+ if (grub_errno == GRUB_ERR_NONE) |
|
| 399 |
-+ {
|
|
| 400 |
-+ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); |
|
| 401 |
-+ loaded = 1; |
|
| 402 |
-+ lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; |
|
| 403 |
-+ } |
|
| 404 |
-+ |
|
| 405 |
-+ memcpy(params, &lh, 2 * 512); |
|
| 406 |
-+ |
|
| 407 |
-+ params->type_of_loader = 0x21; |
|
| 408 |
-+ |
|
| 409 |
-+ fail: |
|
| 410 |
-+ |
|
| 411 |
-+ if (file) |
|
| 412 |
-+ grub_file_close (file); |
|
| 413 |
-+ |
|
| 414 |
-+ if (grub_errno != GRUB_ERR_NONE) |
|
| 415 |
-+ {
|
|
| 416 |
-+ grub_dl_unref (my_mod); |
|
| 417 |
-+ loaded = 0; |
|
| 418 |
-+ } |
|
| 419 |
-+ |
|
| 420 |
-+ if (linux_cmdline && !loaded) |
|
| 421 |
-+ grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1)); |
|
| 422 |
-+ |
|
| 423 |
-+ if (kernel_mem && !loaded) |
|
| 424 |
-+ grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); |
|
| 425 |
-+ |
|
| 426 |
-+ if (params && !loaded) |
|
| 427 |
-+ grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); |
|
| 428 |
-+ |
|
| 429 |
-+ return grub_errno; |
|
| 430 |
-+} |
|
| 431 |
-+ |
|
| 432 |
-+static grub_command_t cmd_linux, cmd_initrd; |
|
| 433 |
-+ |
|
| 434 |
-+GRUB_MOD_INIT(linuxefi) |
|
| 435 |
-+{
|
|
| 436 |
-+ cmd_linux = |
|
| 437 |
-+ grub_register_command ("linuxefi", grub_cmd_linux,
|
|
| 438 |
-+ 0, N_("Load Linux."));
|
|
| 439 |
-+ cmd_initrd = |
|
| 440 |
-+ grub_register_command ("initrdefi", grub_cmd_initrd,
|
|
| 441 |
-+ 0, N_("Load initrd."));
|
|
| 442 |
-+ my_mod = mod; |
|
| 443 |
-+} |
|
| 444 |
-+ |
|
| 445 |
-+GRUB_MOD_FINI(linuxefi) |
|
| 446 |
-+{
|
|
| 447 |
-+ grub_unregister_command (cmd_linux); |
|
| 448 |
-+ grub_unregister_command (cmd_initrd); |
|
| 449 |
-+} |
|
| 450 |
-diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h |
|
| 451 |
-index 0e6fd86..9a2da0e 100644 |
|
| 452 |
-+++ b/include/grub/efi/efi.h |
|
| 453 |
-@@ -40,6 +40,9 @@ void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds); |
|
| 454 |
- void * |
|
| 455 |
- EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address, |
|
| 456 |
- grub_efi_uintn_t pages); |
|
| 457 |
-+void * |
|
| 458 |
-+EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max, |
|
| 459 |
-+ grub_efi_uintn_t pages); |
|
| 460 |
- void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, |
|
| 461 |
- grub_efi_uintn_t pages); |
|
| 462 |
- int |
|
| 463 |
-diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h |
|
| 464 |
-index da0ca3b..fc36bda 100644 |
|
| 465 |
-+++ b/include/grub/i386/linux.h |
|
| 466 |
-@@ -139,6 +139,7 @@ struct linux_kernel_header |
|
| 467 |
- grub_uint64_t setup_data; |
|
| 468 |
- grub_uint64_t pref_address; |
|
| 469 |
- grub_uint32_t init_size; |
|
| 470 |
-+ grub_uint32_t handover_offset; |
|
| 471 |
- } GRUB_PACKED; |
|
| 472 |
- |
|
| 473 |
- /* Boot parameters for Linux based on 2.6.12. This is used by the setup |
|
| 474 |
-2.9.3 |
|
| 475 |
- |
| 476 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,117 +0,0 @@ |
| 1 |
-From 9d70f7f9a356d965ed48963e2ead12af8de97615 Mon Sep 17 00:00:00 2001 |
|
| 2 |
-From: Colin Watson <cjwatson@ubuntu.com> |
|
| 3 |
-Date: Tue, 23 Oct 2012 10:40:49 -0400 |
|
| 4 |
-Subject: [PATCH 22/90] Don't allow insmod when secure boot is enabled. |
|
| 5 |
- |
|
| 6 |
-Hi, |
|
| 7 |
- |
|
| 8 |
-Fedora's patch to forbid insmod in UEFI Secure Boot environments is fine |
|
| 9 |
-as far as it goes. However, the insmod command is not the only way that |
|
| 10 |
-modules can be loaded. In particular, the 'normal' command, which |
|
| 11 |
-implements the usual GRUB menu and the fully-featured command prompt, |
|
| 12 |
-will implicitly load commands not currently loaded into memory. This |
|
| 13 |
-permits trivial Secure Boot violations by writing commands implementing |
|
| 14 |
-whatever you want to do and pointing $prefix at the malicious code. |
|
| 15 |
- |
|
| 16 |
-I'm currently test-building this patch (replacing your current |
|
| 17 |
-grub-2.00-no-insmod-on-sb.patch), but this should be more correct. It |
|
| 18 |
-moves the check into grub_dl_load_file. |
|
| 19 |
- grub-core/kern/dl.c | 22 ++++++++++++++++++++++ |
|
| 20 |
- grub-core/kern/efi/efi.c | 28 ++++++++++++++++++++++++++++ |
|
| 21 |
- include/grub/efi/efi.h | 1 + |
|
| 22 |
- 3 files changed, 51 insertions(+) |
|
| 23 |
- |
|
| 24 |
-diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c |
|
| 25 |
-index e394cd9..6210709 100644 |
|
| 26 |
-+++ b/grub-core/kern/dl.c |
|
| 27 |
-@@ -32,6 +32,14 @@ |
|
| 28 |
- #define GRUB_MODULES_MACHINE_READONLY |
|
| 29 |
- #endif |
|
| 30 |
- |
|
| 31 |
-+#ifdef GRUB_MACHINE_EMU |
|
| 32 |
-+#include <sys/mman.h> |
|
| 33 |
-+#endif |
|
| 34 |
-+ |
|
| 35 |
-+#ifdef GRUB_MACHINE_EFI |
|
| 36 |
-+#include <grub/efi/efi.h> |
|
| 37 |
-+#endif |
|
| 38 |
-+ |
|
| 39 |
- |
|
| 40 |
- |
|
| 41 |
- #pragma GCC diagnostic ignored "-Wcast-align" |
|
| 42 |
-@@ -686,6 +695,19 @@ grub_dl_load_file (const char *filename) |
|
| 43 |
- void *core = 0; |
|
| 44 |
- grub_dl_t mod = 0; |
|
| 45 |
- |
|
| 46 |
-+#ifdef GRUB_MACHINE_EFI |
|
| 47 |
-+ if (grub_efi_secure_boot ()) |
|
| 48 |
-+ {
|
|
| 49 |
-+#if 0 |
|
| 50 |
-+ /* This is an error, but grub2-mkconfig still generates a pile of |
|
| 51 |
-+ * insmod commands, so emitting it would be mostly just obnoxious. */ |
|
| 52 |
-+ grub_error (GRUB_ERR_ACCESS_DENIED, |
|
| 53 |
-+ "Secure Boot forbids loading module from %s", filename); |
|
| 54 |
-+#endif |
|
| 55 |
-+ return 0; |
|
| 56 |
-+ } |
|
| 57 |
-+#endif |
|
| 58 |
-+ |
|
| 59 |
- grub_boot_time ("Loading module %s", filename);
|
|
| 60 |
- |
|
| 61 |
- file = grub_file_open (filename); |
|
| 62 |
-diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c |
|
| 63 |
-index 101307f..0859910 100644 |
|
| 64 |
-+++ b/grub-core/kern/efi/efi.c |
|
| 65 |
-@@ -269,6 +269,34 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, |
|
| 66 |
- return NULL; |
|
| 67 |
- } |
|
| 68 |
- |
|
| 69 |
-+grub_efi_boolean_t |
|
| 70 |
-+grub_efi_secure_boot (void) |
|
| 71 |
-+{
|
|
| 72 |
-+ grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; |
|
| 73 |
-+ grub_size_t datasize; |
|
| 74 |
-+ char *secure_boot = NULL; |
|
| 75 |
-+ char *setup_mode = NULL; |
|
| 76 |
-+ grub_efi_boolean_t ret = 0; |
|
| 77 |
-+ |
|
| 78 |
-+ secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize);
|
|
| 79 |
-+ |
|
| 80 |
-+ if (datasize != 1 || !secure_boot) |
|
| 81 |
-+ goto out; |
|
| 82 |
-+ |
|
| 83 |
-+ setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize);
|
|
| 84 |
-+ |
|
| 85 |
-+ if (datasize != 1 || !setup_mode) |
|
| 86 |
-+ goto out; |
|
| 87 |
-+ |
|
| 88 |
-+ if (*secure_boot && !*setup_mode) |
|
| 89 |
-+ ret = 1; |
|
| 90 |
-+ |
|
| 91 |
-+ out: |
|
| 92 |
-+ grub_free (secure_boot); |
|
| 93 |
-+ grub_free (setup_mode); |
|
| 94 |
-+ return ret; |
|
| 95 |
-+} |
|
| 96 |
-+ |
|
| 97 |
- #pragma GCC diagnostic ignored "-Wcast-align" |
|
| 98 |
- |
|
| 99 |
- /* Search the mods section from the PE32/PE32+ image. This code uses |
|
| 100 |
-diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h |
|
| 101 |
-index 9a2da0e..2245632 100644 |
|
| 102 |
-+++ b/include/grub/efi/efi.h |
|
| 103 |
-@@ -76,6 +76,7 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var, |
|
| 104 |
- const grub_efi_guid_t *guid, |
|
| 105 |
- void *data, |
|
| 106 |
- grub_size_t datasize); |
|
| 107 |
-+grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void); |
|
| 108 |
- int |
|
| 109 |
- EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, |
|
| 110 |
- const grub_efi_device_path_t *dp2); |
|
| 111 |
-2.9.3 |
|
| 112 |
- |
| ... | ... |
@@ -3,18 +3,15 @@ |
| 3 | 3 |
Summary: GRand Unified Bootloader |
| 4 | 4 |
Name: grub2-efi |
| 5 | 5 |
Version: 2.02 |
| 6 |
-Release: 6%{?dist}
|
|
| 6 |
+Release: 7%{?dist}
|
|
| 7 | 7 |
License: GPLv3+ |
| 8 | 8 |
URL: http://www.gnu.org/software/grub |
| 9 | 9 |
Group: Applications/System |
| 10 | 10 |
Vendor: VMware, Inc. |
| 11 | 11 |
Distribution: Photon |
| 12 |
-Source0: http://alpha.gnu.org/gnu/grub/grub-2.02~beta3.tar.xz |
|
| 13 |
-%define sha1 grub=14a1f9239a9c974957e835dc706fc6a1e4819c83 |
|
| 14 |
-Patch0: 0020-Add-support-for-linuxefi.patch |
|
| 15 |
-Patch1: 0022-Don-t-allow-insmod-when-secure-boot-is-enabled.patch |
|
| 16 |
-Patch2: linuxefi_require_shim.patch |
|
| 17 |
-Patch3: linuxefi_non_sb_fallback.patch |
|
| 12 |
+Source0: http://alpha.gnu.org/gnu/grub/grub-2.02~rc2.tar.xz |
|
| 13 |
+%define sha1 grub=4f6f3719fd7dbb0449a58547c1b08c9801337663 |
|
| 14 |
+Patch0: 0001-Secure-Boot-support.patch |
|
| 18 | 15 |
BuildRequires: device-mapper-devel |
| 19 | 16 |
BuildRequires: xz-devel |
| 20 | 17 |
BuildRequires: systemd-devel |
| ... | ... |
@@ -32,11 +29,8 @@ These are the additional language files of grub. |
| 32 | 32 |
|
| 33 | 33 |
|
| 34 | 34 |
%prep |
| 35 |
-%setup -qn grub-2.02~beta3 |
|
| 35 |
+%setup -qn grub-2.02~rc2 |
|
| 36 | 36 |
%patch0 -p1 |
| 37 |
-%patch1 -p1 |
|
| 38 |
-%patch2 -p1 |
|
| 39 |
-%patch3 -p1 |
|
| 40 | 37 |
%build |
| 41 | 38 |
./autogen.sh |
| 42 | 39 |
./configure \ |
| ... | ... |
@@ -90,6 +84,9 @@ rm -rf %{buildroot}%{_infodir}
|
| 90 | 90 |
/usr/share/locale/* |
| 91 | 91 |
|
| 92 | 92 |
%changelog |
| 93 |
+* Fri Apr 14 2017 Alexey Makhalov <amakhalov@vmware.com> 2.02-7 |
|
| 94 |
+- Version update to 2.02~rc2 |
|
| 95 |
+- SecureBoot hardening: forbid unsigned vmlinuz image |
|
| 93 | 96 |
* Wed Mar 22 2017 Alexey Makhalov <amakhalov@vmware.com> 2.02-6 |
| 94 | 97 |
- Version update to 2.02~beta3 |
| 95 | 98 |
- SecureBoot support |
| 96 | 99 |
deleted file mode 100644 |
| ... | ... |
@@ -1,96 +0,0 @@ |
| 1 |
-From bbee35754c088eca0ffada3ed7457a2fe674de69 Mon Sep 17 00:00:00 2001 |
|
| 2 |
-From: Colin Watson <cjwatson@ubuntu.com> |
|
| 3 |
-Date: Mon, 13 Jan 2014 12:13:20 +0000 |
|
| 4 |
-Subject: If running under UEFI secure boot, attempt to use linuxefi loader |
|
| 5 |
- |
|
| 6 |
-Author: Steve Langasek <steve.langasek@canonical.com> |
|
| 7 |
-Forwarded: no |
|
| 8 |
-Last-Update: 2013-12-20 |
|
| 9 |
- |
|
| 10 |
-Patch-Name: linuxefi_non_sb_fallback.patch |
|
| 11 |
- grub-core/loader/i386/efi/linux.c | 2 +- |
|
| 12 |
- grub-core/loader/i386/linux.c | 43 +++++++++++++++++++++++++++++++++++++++ |
|
| 13 |
- 2 files changed, 44 insertions(+), 1 deletion(-) |
|
| 14 |
- |
|
| 15 |
-diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c |
|
| 16 |
-index f764f49..88e2d34 100644 |
|
| 17 |
-+++ b/grub-core/loader/i386/efi/linux.c |
|
| 18 |
-@@ -234,7 +234,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
|
| 19 |
- |
|
| 20 |
- if (! grub_linuxefi_secure_validate (kernel, filelen)) |
|
| 21 |
- {
|
|
| 22 |
-- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
|
|
| 23 |
-+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("%s has invalid signature"), argv[0]);
|
|
| 24 |
- grub_free (kernel); |
|
| 25 |
- goto fail; |
|
| 26 |
- } |
|
| 27 |
-diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c |
|
| 28 |
-index 31fb91e..2380642 100644 |
|
| 29 |
-+++ b/grub-core/loader/i386/linux.c |
|
| 30 |
-@@ -76,6 +76,8 @@ static grub_size_t maximal_cmdline_size; |
|
| 31 |
- static struct linux_kernel_params linux_params; |
|
| 32 |
- static char *linux_cmdline; |
|
| 33 |
- #ifdef GRUB_MACHINE_EFI |
|
| 34 |
-+static int using_linuxefi; |
|
| 35 |
-+static grub_command_t initrdefi_cmd; |
|
| 36 |
- static grub_efi_uintn_t efi_mmap_size; |
|
| 37 |
- #else |
|
| 38 |
- static const grub_size_t efi_mmap_size = 0; |
|
| 39 |
-@@ -690,6 +692,41 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
|
| 40 |
- |
|
| 41 |
- grub_dl_ref (my_mod); |
|
| 42 |
- |
|
| 43 |
-+#ifdef GRUB_MACHINE_EFI |
|
| 44 |
-+ using_linuxefi = 0; |
|
| 45 |
-+ if (grub_efi_secure_boot ()) |
|
| 46 |
-+ {
|
|
| 47 |
-+ /* Try linuxefi first, which will require a successful signature check |
|
| 48 |
-+ and then hand over to the kernel without calling ExitBootServices. |
|
| 49 |
-+ If that fails, however, fall back to calling ExitBootServices |
|
| 50 |
-+ ourselves and then booting an unsigned kernel. */ |
|
| 51 |
-+ grub_dl_t mod; |
|
| 52 |
-+ grub_command_t linuxefi_cmd; |
|
| 53 |
-+ |
|
| 54 |
-+ grub_dprintf ("linux", "Secure Boot enabled: trying linuxefi\n");
|
|
| 55 |
-+ |
|
| 56 |
-+ mod = grub_dl_load ("linuxefi");
|
|
| 57 |
-+ if (mod) |
|
| 58 |
-+ {
|
|
| 59 |
-+ grub_dl_ref (mod); |
|
| 60 |
-+ linuxefi_cmd = grub_command_find ("linuxefi");
|
|
| 61 |
-+ initrdefi_cmd = grub_command_find ("initrdefi");
|
|
| 62 |
-+ if (linuxefi_cmd && initrdefi_cmd) |
|
| 63 |
-+ {
|
|
| 64 |
-+ (linuxefi_cmd->func) (linuxefi_cmd, argc, argv); |
|
| 65 |
-+ if (grub_errno == GRUB_ERR_NONE) |
|
| 66 |
-+ {
|
|
| 67 |
-+ grub_dprintf ("linux", "Handing off to linuxefi\n");
|
|
| 68 |
-+ using_linuxefi = 1; |
|
| 69 |
-+ return GRUB_ERR_NONE; |
|
| 70 |
-+ } |
|
| 71 |
-+ grub_dprintf ("linux", "linuxefi failed (%d)\n", grub_errno);
|
|
| 72 |
-+ grub_errno = GRUB_ERR_NONE; |
|
| 73 |
-+ } |
|
| 74 |
-+ } |
|
| 75 |
-+ } |
|
| 76 |
-+#endif |
|
| 77 |
-+ |
|
| 78 |
- if (argc == 0) |
|
| 79 |
- {
|
|
| 80 |
- grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
|
| 81 |
-@@ -1052,6 +1089,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), |
|
| 82 |
- grub_err_t err; |
|
| 83 |
- struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
|
|
| 84 |
- |
|
| 85 |
-+#ifdef GRUB_MACHINE_EFI |
|
| 86 |
-+ /* If we're using linuxefi, just forward to initrdefi. */ |
|
| 87 |
-+ if (using_linuxefi && initrdefi_cmd) |
|
| 88 |
-+ return (initrdefi_cmd->func) (initrdefi_cmd, argc, argv); |
|
| 89 |
-+#endif |
|
| 90 |
-+ |
|
| 91 |
- if (argc == 0) |
|
| 92 |
- {
|
|
| 93 |
- grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
| 94 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,28 +0,0 @@ |
| 1 |
-From f393f2edf39bc9fc12cd6e6dab6cd1e40b149ac2 Mon Sep 17 00:00:00 2001 |
|
| 2 |
-From: Colin Watson <cjwatson@ubuntu.com> |
|
| 3 |
-Date: Mon, 13 Jan 2014 12:13:19 +0000 |
|
| 4 |
-Subject: Make linuxefi refuse to boot without shim |
|
| 5 |
- |
|
| 6 |
-This is only intended as a temporary measure. |
|
| 7 |
- |
|
| 8 |
-Forwarded: not-needed |
|
| 9 |
-Last-Update: 2013-01-29 |
|
| 10 |
- |
|
| 11 |
-Patch-Name: linuxefi_require_shim.patch |
|
| 12 |
- grub-core/loader/i386/efi/linux.c | 2 +- |
|
| 13 |
- 1 file changed, 1 insertion(+), 1 deletion(-) |
|
| 14 |
- |
|
| 15 |
-diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c |
|
| 16 |
-index 2bf38fa..f764f49 100644 |
|
| 17 |
-+++ b/grub-core/loader/i386/efi/linux.c |
|
| 18 |
-@@ -63,7 +63,7 @@ grub_linuxefi_secure_validate (void *data, grub_uint32_t size) |
|
| 19 |
- shim_lock = grub_efi_locate_protocol(&guid, NULL); |
|
| 20 |
- |
|
| 21 |
- if (!shim_lock) |
|
| 22 |
-- return 1; |
|
| 23 |
-+ return 0; |
|
| 24 |
- |
|
| 25 |
- if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS) |
|
| 26 |
- return 1; |
| 27 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,45 +0,0 @@ |
| 1 |
-From 88c9657960a6c5d3673a25c266781e876c181add Mon Sep 17 00:00:00 2001 |
|
| 2 |
-From: Hector Marco-Gisbert <hecmargi@upv.es> |
|
| 3 |
-Date: Fri, 13 Nov 2015 16:21:09 +0100 |
|
| 4 |
-Subject: [PATCH] Fix security issue when reading username and password |
|
| 5 |
- |
|
| 6 |
- This patch fixes two integer underflows at: |
|
| 7 |
- * grub-core/lib/crypto.c |
|
| 8 |
- * grub-core/normal/auth.c |
|
| 9 |
- |
|
| 10 |
-Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es> |
|
| 11 |
-Signed-off-by: Ismael Ripoll-Ripoll <iripoll@disca.upv.es> |
|
| 12 |
- grub-core/lib/crypto.c | 2 +- |
|
| 13 |
- grub-core/normal/auth.c | 2 +- |
|
| 14 |
- 2 files changed, 2 insertions(+), 2 deletions(-) |
|
| 15 |
- |
|
| 16 |
-diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c |
|
| 17 |
-index 010e550..524a3d8 100644 |
|
| 18 |
-+++ b/grub-core/lib/crypto.c |
|
| 19 |
-@@ -468,7 +468,7 @@ grub_password_get (char buf[], unsigned buf_size) |
|
| 20 |
- break; |
|
| 21 |
- } |
|
| 22 |
- |
|
| 23 |
-- if (key == '\b') |
|
| 24 |
-+ if (key == '\b' && cur_len) |
|
| 25 |
- {
|
|
| 26 |
- cur_len--; |
|
| 27 |
- continue; |
|
| 28 |
-diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c |
|
| 29 |
-index c6bd96e..5782ec5 100644 |
|
| 30 |
-+++ b/grub-core/normal/auth.c |
|
| 31 |
-@@ -172,7 +172,7 @@ grub_username_get (char buf[], unsigned buf_size) |
|
| 32 |
- break; |
|
| 33 |
- } |
|
| 34 |
- |
|
| 35 |
-- if (key == '\b') |
|
| 36 |
-+ if (key == '\b' && cur_len) |
|
| 37 |
- {
|
|
| 38 |
- cur_len--; |
|
| 39 |
- grub_printf ("\b");
|
|
| 40 |
-1.9.1 |
|
| 41 |
- |
| ... | ... |
@@ -3,16 +3,15 @@ |
| 3 | 3 |
Summary: GRand Unified Bootloader |
| 4 | 4 |
Name: grub2 |
| 5 | 5 |
Version: 2.02 |
| 6 |
-Release: 7%{?dist}
|
|
| 6 |
+Release: 8%{?dist}
|
|
| 7 | 7 |
License: GPLv3+ |
| 8 | 8 |
URL: http://www.gnu.org/software/grub |
| 9 | 9 |
Group: Applications/System |
| 10 | 10 |
Vendor: VMware, Inc. |
| 11 | 11 |
Distribution: Photon |
| 12 |
-Source0: http://alpha.gnu.org/gnu/grub/grub-2.02~beta2.tar.gz |
|
| 13 |
-%define sha1 grub=b2c9227f9a54587532ae3f727d197ab112cdbbb3 |
|
| 12 |
+Source0: http://alpha.gnu.org/gnu/grub/grub-2.02~rc2.tar.xz |
|
| 13 |
+%define sha1 grub=4f6f3719fd7dbb0449a58547c1b08c9801337663 |
|
| 14 | 14 |
Patch0: Fix_to_boot_entries_with_out_password.patch |
| 15 |
-Patch1: grub2-CVE-2015-8370.patch |
|
| 16 | 15 |
BuildRequires: device-mapper-devel |
| 17 | 16 |
BuildRequires: xz-devel |
| 18 | 17 |
BuildRequires: systemd-devel |
| ... | ... |
@@ -30,10 +29,8 @@ These are the additional language files of grub. |
| 30 | 30 |
|
| 31 | 31 |
|
| 32 | 32 |
%prep |
| 33 |
-%setup -qn grub-2.02~beta2 |
|
| 33 |
+%setup -qn grub-2.02~rc2 |
|
| 34 | 34 |
%patch0 -p1 |
| 35 |
-%patch1 -p1 |
|
| 36 |
-#sed -i -e '/gets is a/d' grub-core/gnulib/stdio.in.h |
|
| 37 | 35 |
%build |
| 38 | 36 |
./configure \ |
| 39 | 37 |
--prefix=%{_prefix} \
|
| ... | ... |
@@ -81,6 +78,8 @@ rm -rf %{buildroot}%{_infodir}
|
| 81 | 81 |
/usr/share/locale/* |
| 82 | 82 |
|
| 83 | 83 |
%changelog |
| 84 |
+* Fri Apr 14 2017 Alexey Makhalov <amakhalov@vmware.com> 2.02-8 |
|
| 85 |
+- Version update to 2.02~rc2 |
|
| 84 | 86 |
* Fri Nov 18 2016 Anish Swaminathan <anishs@vmware.com> 2.02-7 |
| 85 | 87 |
- Add fix for CVE-2015-8370 |
| 86 | 88 |
* Fri Nov 18 2016 Anish Swaminathan <anishs@vmware.com> 2.02-6 |
| 87 | 89 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,7 @@ |
| 0 |
+#! /bin/bash |
|
| 1 |
+./mk-efiboot-img.sh |
|
| 2 |
+mkisofs -R -l -L -D -b isolinux/isolinux.bin -c isolinux/boot.cat \ |
|
| 3 |
+ -no-emul-boot -boot-load-size 4 -boot-info-table \ |
|
| 4 |
+ -eltorito-alt-boot -e efi/boot/efiboot.img -no-emul-boot \ |
|
| 5 |
+ -V "PHOTON_$(date +%Y%m%d)" \ |
|
| 6 |
+ ./BUILD_DVD/ > 1.iso |
| ... | ... |
@@ -15,7 +15,7 @@ mcopy -s -i $IMAGE $EFI_DIR '::/' |
| 15 | 15 |
# # make VENDOR_CERT_FILE=<VMware cert> RELEASE=1 EFI_PATH=/usr/lib 'DEFAULT_LOADER=\\\\grubx64.efi' shim.efi |
| 16 | 16 |
# # mv shim.efi bootx64.efi |
| 17 | 17 |
|
| 18 |
-# grubx64.efi is generated on Photon OS by using grub2-efi-2.02-6: |
|
| 18 |
+# grubx64.efi is generated on Photon OS by using grub2-efi >= 2.02-7: |
|
| 19 | 19 |
# # grub2-efi-mkimage -o grubx64.efi -p /boot/grub2 -O x86_64-efi fat iso9660 part_gpt part_msdos normal boot linux configfile loopback chain efifwsetup efi_gop efi_uga ls search search_label search_fs_uuid search_fs_file gfxterm gfxterm_background gfxterm_menu test all_video loadenv exfat ext2 udf halt gfxmenu png tga lsefi help linuxefi |
| 20 | 20 |
|
| 21 | 21 |
# both bootx64.efi and grubx64.efi are signed with VMware key |