Browse code

SecureBoot in VM support

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>

Alexey Makhalov authored on 2017/04/15 07:40:12
Showing 13 changed files
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
0 7
Binary files a/installer/BUILD_DVD/boot/grub2/efiboot.img and b/installer/BUILD_DVD/boot/grub2/efiboot.img differ
1 8
old mode 100755
2 9
new mode 100644
3 10
Binary files a/installer/EFI/BOOT/bootx64.efi and b/installer/EFI/BOOT/bootx64.efi differ
4 11
Binary files a/installer/EFI/BOOT/grubx64.efi and b/installer/EFI/BOOT/grubx64.efi differ
... ...
@@ -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