Change-Id: I51baf6b1ef8df582358b92e0b6277e2de3733cc4
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/2859
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
1 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,663 +0,0 @@ |
1 |
-From e5d5e5a259a9827e4d6e41e49085f730c773c178 Mon Sep 17 00:00:00 2001 |
|
2 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
3 |
-Date: Tue, 10 Jul 2012 11:58:52 -0400 |
|
4 |
-Subject: [PATCH] Secure Boot support |
|
5 |
- |
|
6 |
-New commands: linuxefi, initrdefi |
|
7 |
-If running under secure boot use linuxefi loader only and linux |
|
8 |
-command is fallback to linuxefi. |
|
9 |
-Forbid dl file loading (insmod and similar) when secure boot is enabled. |
|
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 | 387 ++++++++++++++++++++++++++++++++++++++ |
|
15 |
- grub-core/loader/i386/linux.c | 45 +++++ |
|
16 |
- include/grub/efi/efi.h | 4 + |
|
17 |
- include/grub/i386/linux.h | 1 + |
|
18 |
- 8 files changed, 528 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 |
-+++ b/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 |
-+++ b/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 |
-+++ b/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 |
-+++ b/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..78bc216 |
|
162 |
-+++ b/grub-core/loader/i386/efi/linux.c |
|
163 |
-@@ -0,0 +1,387 @@ |
|
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 |
-+ grub_free (kernel); |
|
396 |
-+ goto fail; |
|
397 |
-+ } |
|
398 |
-+ |
|
399 |
-+ if (! grub_linuxefi_secure_validate (kernel, filelen)) |
|
400 |
-+ { |
|
401 |
-+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("%s has invalid signature"), argv[0]); |
|
402 |
-+ grub_free (kernel); |
|
403 |
-+ goto fail; |
|
404 |
-+ } |
|
405 |
-+ |
|
406 |
-+ grub_file_seek (file, 0); |
|
407 |
-+ |
|
408 |
-+ grub_free(kernel); |
|
409 |
-+ |
|
410 |
-+ params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); |
|
411 |
-+ |
|
412 |
-+ if (! params) |
|
413 |
-+ { |
|
414 |
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); |
|
415 |
-+ goto fail; |
|
416 |
-+ } |
|
417 |
-+ |
|
418 |
-+ memset (params, 0, 16384); |
|
419 |
-+ |
|
420 |
-+ if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) |
|
421 |
-+ { |
|
422 |
-+ if (!grub_errno) |
|
423 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), |
|
424 |
-+ argv[0]); |
|
425 |
-+ goto fail; |
|
426 |
-+ } |
|
427 |
-+ |
|
428 |
-+ if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) |
|
429 |
-+ { |
|
430 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number")); |
|
431 |
-+ goto fail; |
|
432 |
-+ } |
|
433 |
-+ |
|
434 |
-+ if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) |
|
435 |
-+ { |
|
436 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors")); |
|
437 |
-+ goto fail; |
|
438 |
-+ } |
|
439 |
-+ |
|
440 |
-+ if (lh.version < grub_cpu_to_le16 (0x020b)) |
|
441 |
-+ { |
|
442 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("kernel too old")); |
|
443 |
-+ goto fail; |
|
444 |
-+ } |
|
445 |
-+ |
|
446 |
-+ if (!lh.handover_offset) |
|
447 |
-+ { |
|
448 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover")); |
|
449 |
-+ goto fail; |
|
450 |
-+ } |
|
451 |
-+ |
|
452 |
-+ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, |
|
453 |
-+ BYTES_TO_PAGES(lh.cmdline_size + 1)); |
|
454 |
-+ |
|
455 |
-+ if (!linux_cmdline) |
|
456 |
-+ { |
|
457 |
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); |
|
458 |
-+ goto fail; |
|
459 |
-+ } |
|
460 |
-+ |
|
461 |
-+ grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); |
|
462 |
-+ grub_create_loader_cmdline (argc, argv, |
|
463 |
-+ linux_cmdline + sizeof (LINUX_IMAGE) - 1, |
|
464 |
-+ lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1)); |
|
465 |
-+ |
|
466 |
-+ lh.cmd_line_ptr = (grub_uint32_t)(grub_uint64_t)linux_cmdline; |
|
467 |
-+ |
|
468 |
-+ handover_offset = lh.handover_offset; |
|
469 |
-+ |
|
470 |
-+ start = (lh.setup_sects + 1) * 512; |
|
471 |
-+ len = grub_file_size(file) - start; |
|
472 |
-+ |
|
473 |
-+ kernel_mem = grub_efi_allocate_pages(lh.pref_address, |
|
474 |
-+ BYTES_TO_PAGES(lh.init_size)); |
|
475 |
-+ |
|
476 |
-+ if (!kernel_mem) |
|
477 |
-+ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, |
|
478 |
-+ BYTES_TO_PAGES(lh.init_size)); |
|
479 |
-+ |
|
480 |
-+ if (!kernel_mem) |
|
481 |
-+ { |
|
482 |
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); |
|
483 |
-+ goto fail; |
|
484 |
-+ } |
|
485 |
-+ |
|
486 |
-+ if (grub_file_seek (file, start) == (grub_off_t) -1) |
|
487 |
-+ { |
|
488 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), |
|
489 |
-+ argv[0]); |
|
490 |
-+ goto fail; |
|
491 |
-+ } |
|
492 |
-+ |
|
493 |
-+ if (grub_file_read (file, kernel_mem, len) != len && !grub_errno) |
|
494 |
-+ { |
|
495 |
-+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), |
|
496 |
-+ argv[0]); |
|
497 |
-+ } |
|
498 |
-+ |
|
499 |
-+ if (grub_errno == GRUB_ERR_NONE) |
|
500 |
-+ { |
|
501 |
-+ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); |
|
502 |
-+ loaded = 1; |
|
503 |
-+ lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; |
|
504 |
-+ } |
|
505 |
-+ |
|
506 |
-+ memcpy(params, &lh, 2 * 512); |
|
507 |
-+ |
|
508 |
-+ params->type_of_loader = 0x21; |
|
509 |
-+ |
|
510 |
-+ fail: |
|
511 |
-+ fail_errno = grub_errno; |
|
512 |
-+ if (file) |
|
513 |
-+ grub_file_close (file); |
|
514 |
-+ |
|
515 |
-+ if (fail_errno != GRUB_ERR_NONE) |
|
516 |
-+ { |
|
517 |
-+ grub_dl_unref (my_mod); |
|
518 |
-+ loaded = 0; |
|
519 |
-+ } |
|
520 |
-+ |
|
521 |
-+ if (linux_cmdline && !loaded) |
|
522 |
-+ grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1)); |
|
523 |
-+ |
|
524 |
-+ if (kernel_mem && !loaded) |
|
525 |
-+ grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); |
|
526 |
-+ |
|
527 |
-+ if (params && !loaded) |
|
528 |
-+ grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); |
|
529 |
-+ |
|
530 |
-+ return fail_errno; |
|
531 |
-+} |
|
532 |
-+ |
|
533 |
-+static grub_command_t cmd_linux, cmd_initrd; |
|
534 |
-+ |
|
535 |
-+GRUB_MOD_INIT(linuxefi) |
|
536 |
-+{ |
|
537 |
-+ cmd_linux = |
|
538 |
-+ grub_register_command ("linuxefi", grub_cmd_linux, |
|
539 |
-+ 0, N_("Load Linux.")); |
|
540 |
-+ cmd_initrd = |
|
541 |
-+ grub_register_command ("initrdefi", grub_cmd_initrd, |
|
542 |
-+ 0, N_("Load initrd.")); |
|
543 |
-+ my_mod = mod; |
|
544 |
-+} |
|
545 |
-+ |
|
546 |
-+GRUB_MOD_FINI(linuxefi) |
|
547 |
-+{ |
|
548 |
-+ grub_unregister_command (cmd_linux); |
|
549 |
-+ grub_unregister_command (cmd_initrd); |
|
550 |
-+} |
|
551 |
-diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c |
|
552 |
-index b15b8cc..fce1b45 100644 |
|
553 |
-+++ b/grub-core/loader/i386/linux.c |
|
554 |
-@@ -75,6 +75,8 @@ static grub_size_t maximal_cmdline_size; |
|
555 |
- static struct linux_kernel_params linux_params; |
|
556 |
- static char *linux_cmdline; |
|
557 |
- #ifdef GRUB_MACHINE_EFI |
|
558 |
-+static int using_linuxefi; |
|
559 |
-+static grub_command_t initrdefi_cmd; |
|
560 |
- static grub_efi_uintn_t efi_mmap_size; |
|
561 |
- #else |
|
562 |
- static const grub_size_t efi_mmap_size = 0; |
|
563 |
-@@ -689,6 +691,43 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
|
564 |
- |
|
565 |
- grub_dl_ref (my_mod); |
|
566 |
- |
|
567 |
-+#ifdef GRUB_MACHINE_EFI |
|
568 |
-+ using_linuxefi = 0; |
|
569 |
-+ if (grub_efi_secure_boot ()) |
|
570 |
-+ { |
|
571 |
-+ /* Use linuxefi if SB is enabled, which will require a successful |
|
572 |
-+ signature check and then hand over to the kernel without calling |
|
573 |
-+ ExitBootServices. |
|
574 |
-+ If that fails, however, DO NOT fall back to original 'linux' |
|
575 |
-+ command which boots an unsigned kernel. */ |
|
576 |
-+ grub_dl_t mod; |
|
577 |
-+ grub_command_t linuxefi_cmd; |
|
578 |
-+ |
|
579 |
-+ grub_dprintf ("linux", "Secure Boot enabled: trying linuxefi\n"); |
|
580 |
-+ |
|
581 |
-+ mod = grub_dl_load ("linuxefi"); |
|
582 |
-+ if (mod) |
|
583 |
-+ { |
|
584 |
-+ grub_dl_ref (mod); |
|
585 |
-+ linuxefi_cmd = grub_command_find ("linuxefi"); |
|
586 |
-+ initrdefi_cmd = grub_command_find ("initrdefi"); |
|
587 |
-+ if (linuxefi_cmd && initrdefi_cmd) |
|
588 |
-+ { |
|
589 |
-+ (linuxefi_cmd->func) (linuxefi_cmd, argc, argv); |
|
590 |
-+ if (grub_errno == GRUB_ERR_NONE) |
|
591 |
-+ { |
|
592 |
-+ grub_dprintf ("linux", "Handing off to linuxefi\n"); |
|
593 |
-+ using_linuxefi = 1; |
|
594 |
-+ return GRUB_ERR_NONE; |
|
595 |
-+ } |
|
596 |
-+ grub_dprintf ("linux", "linuxefi failed (%d)\n", grub_errno); |
|
597 |
-+ grub_errno = GRUB_ERR_ACCESS_DENIED; |
|
598 |
-+ } |
|
599 |
-+ } |
|
600 |
-+ goto fail; |
|
601 |
-+ } |
|
602 |
-+#endif |
|
603 |
-+ |
|
604 |
- if (argc == 0) |
|
605 |
- { |
|
606 |
- grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); |
|
607 |
-@@ -1051,6 +1090,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), |
|
608 |
- grub_err_t err; |
|
609 |
- struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; |
|
610 |
- |
|
611 |
-+#ifdef GRUB_MACHINE_EFI |
|
612 |
-+ /* If we're using linuxefi, just forward to initrdefi. */ |
|
613 |
-+ if (using_linuxefi && initrdefi_cmd) |
|
614 |
-+ return (initrdefi_cmd->func) (initrdefi_cmd, argc, argv); |
|
615 |
-+#endif |
|
616 |
-+ |
|
617 |
- if (argc == 0) |
|
618 |
- { |
|
619 |
- grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); |
|
620 |
-diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h |
|
621 |
-index e9c601f..62a3d97 100644 |
|
622 |
-+++ b/include/grub/efi/efi.h |
|
623 |
-@@ -40,6 +40,9 @@ void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds); |
|
624 |
- void * |
|
625 |
- EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address, |
|
626 |
- grub_efi_uintn_t pages); |
|
627 |
-+void * |
|
628 |
-+EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max, |
|
629 |
-+ grub_efi_uintn_t pages); |
|
630 |
- void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, |
|
631 |
- grub_efi_uintn_t pages); |
|
632 |
- int |
|
633 |
-@@ -73,6 +76,7 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var, |
|
634 |
- const grub_efi_guid_t *guid, |
|
635 |
- void *data, |
|
636 |
- grub_size_t datasize); |
|
637 |
-+grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void); |
|
638 |
- int |
|
639 |
- EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, |
|
640 |
- const grub_efi_device_path_t *dp2); |
|
641 |
-diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h |
|
642 |
-index da0ca3b..fc36bda 100644 |
|
643 |
-+++ b/include/grub/i386/linux.h |
|
644 |
-@@ -139,6 +139,7 @@ struct linux_kernel_header |
|
645 |
- grub_uint64_t setup_data; |
|
646 |
- grub_uint64_t pref_address; |
|
647 |
- grub_uint32_t init_size; |
|
648 |
-+ grub_uint32_t handover_offset; |
|
649 |
- } GRUB_PACKED; |
|
650 |
- |
|
651 |
- /* Boot parameters for Linux based on 2.6.12. This is used by the setup |
|
652 |
-2.8.1 |
|
653 |
- |
654 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,104 +0,0 @@ |
1 |
-%define debug_package %{nil} |
|
2 |
-%define __os_install_post %{nil} |
|
3 |
-Summary: GRand Unified Bootloader |
|
4 |
-Name: grub2-efi |
|
5 |
-Version: 2.02 |
|
6 |
-Release: 8%{?dist} |
|
7 |
-License: GPLv3+ |
|
8 |
-URL: http://www.gnu.org/software/grub |
|
9 |
-Group: Applications/System |
|
10 |
-Vendor: VMware, Inc. |
|
11 |
-Distribution: Photon |
|
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 |
|
15 |
-BuildRequires: device-mapper-devel |
|
16 |
-BuildRequires: xz-devel |
|
17 |
-BuildRequires: systemd-devel |
|
18 |
-Requires: xz |
|
19 |
-Requires: device-mapper |
|
20 |
-%description |
|
21 |
-The GRUB package contains the GRand Unified Bootloader. |
|
22 |
- |
|
23 |
-%package lang |
|
24 |
-Summary: Additional language files for grub |
|
25 |
-Group: System Environment/Programming |
|
26 |
-Requires: grub2 >= 2.00 |
|
27 |
-%description lang |
|
28 |
-These are the additional language files of grub. |
|
29 |
- |
|
30 |
- |
|
31 |
-%prep |
|
32 |
-%setup -qn grub-2.02~rc2 |
|
33 |
-%patch0 -p1 |
|
34 |
-%build |
|
35 |
-./autogen.sh |
|
36 |
-./configure \ |
|
37 |
- --prefix=%{_prefix} \ |
|
38 |
- --sbindir=/sbin \ |
|
39 |
- --sysconfdir=%{_sysconfdir} \ |
|
40 |
- --disable-grub-emu-usb \ |
|
41 |
- --disable-werror \ |
|
42 |
- --disable-efiemu \ |
|
43 |
- --program-transform-name=s,grub,%{name}, \ |
|
44 |
- --with-grubdir=grub2 \ |
|
45 |
- --with-platform=efi \ |
|
46 |
- --target=x86_64 \ |
|
47 |
- --with-program-prefix="" \ |
|
48 |
- --with-bootdir="/boot" |
|
49 |
- |
|
50 |
-make %{?_smp_mflags} |
|
51 |
- |
|
52 |
-%install |
|
53 |
-make DESTDIR=%{buildroot} install |
|
54 |
-mkdir %{buildroot}%{_sysconfdir}/default |
|
55 |
-touch %{buildroot}%{_sysconfdir}/default/grub |
|
56 |
-mkdir %{buildroot}%{_sysconfdir}/sysconfig |
|
57 |
-ln -sf %{_sysconfdir}/default/grub %{buildroot}%{_sysconfdir}/sysconfig/grub |
|
58 |
-mkdir -p %{buildroot}/boot/%{name} |
|
59 |
-touch %{buildroot}/boot/%{name}/grub.cfg |
|
60 |
-rm -rf %{buildroot}%{_infodir} |
|
61 |
-%post -p /sbin/ldconfig |
|
62 |
-%postun -p /sbin/ldconfig |
|
63 |
-%files |
|
64 |
-%defattr(-,root,root) |
|
65 |
-%dir %{_sysconfdir}/grub.d |
|
66 |
-%config() %{_sysconfdir}/bash_completion.d/grub |
|
67 |
-%config() %{_sysconfdir}/grub.d/00_header |
|
68 |
-%config() %{_sysconfdir}/grub.d/10_linux |
|
69 |
-%config() %{_sysconfdir}/grub.d/20_linux_xen |
|
70 |
-%config() %{_sysconfdir}/grub.d/30_os-prober |
|
71 |
-%config() %{_sysconfdir}/grub.d/40_custom |
|
72 |
-%config() %{_sysconfdir}/grub.d/41_custom |
|
73 |
-%config() %{_sysconfdir}/grub.d/README |
|
74 |
-/sbin/* |
|
75 |
-%{_bindir}/* |
|
76 |
-%{_libdir}/grub/* |
|
77 |
-%{_datarootdir}/grub/* |
|
78 |
-%{_sysconfdir}/sysconfig/grub |
|
79 |
-%{_sysconfdir}/default/grub |
|
80 |
-%ghost %config(noreplace) /boot/%{name}/grub.cfg |
|
81 |
- |
|
82 |
-%files lang |
|
83 |
-%defattr(-,root,root) |
|
84 |
-/usr/share/locale/* |
|
85 |
- |
|
86 |
-%changelog |
|
87 |
-* Thu May 4 2017 Alexey Makhalov <amakhalov@vmware.com> 2.02-8 |
|
88 |
-- linuxefi: free allocated memory on error. |
|
89 |
-* Fri Apr 14 2017 Alexey Makhalov <amakhalov@vmware.com> 2.02-7 |
|
90 |
-- Version update to 2.02~rc2 |
|
91 |
-- SecureBoot hardening: forbid unsigned vmlinuz image |
|
92 |
-* Wed Mar 22 2017 Alexey Makhalov <amakhalov@vmware.com> 2.02-6 |
|
93 |
-- Version update to 2.02~beta3 |
|
94 |
-- SecureBoot support |
|
95 |
-* Fri Nov 18 2016 Anish Swaminathan <anishs@vmware.com> 2.02-5 |
|
96 |
-- Add fix for CVE-2015-8370 |
|
97 |
-* Fri Nov 18 2016 Anish Swaminathan <anishs@vmware.com> 2.02-4 |
|
98 |
-- Change systemd dependency |
|
99 |
-* Thu Oct 06 2016 ChangLee <changlee@vmware.com> 2.02-3 |
|
100 |
-- Modified %check |
|
101 |
-* Tue May 24 2016 Priyesh Padmavilasom <ppadmavilasom@vmware.com> 2.02-2 |
|
102 |
-- GA - Bump release of all rpms |
|
103 |
-* Fri Jul 31 2015 Sharath George <sharathg@vmware.com> 2.02-1 |
|
104 |
-- Adding EFI support. |
105 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,663 @@ |
0 |
+From e5d5e5a259a9827e4d6e41e49085f730c773c178 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 | 387 ++++++++++++++++++++++++++++++++++++++ |
|
15 |
+ grub-core/loader/i386/linux.c | 45 +++++ |
|
16 |
+ include/grub/efi/efi.h | 4 + |
|
17 |
+ include/grub/i386/linux.h | 1 + |
|
18 |
+ 8 files changed, 528 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..78bc216 |
|
162 |
+--- /dev/null |
|
163 |
+@@ -0,0 +1,387 @@ |
|
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 |
++ grub_free (kernel); |
|
396 |
++ goto fail; |
|
397 |
++ } |
|
398 |
++ |
|
399 |
++ if (! grub_linuxefi_secure_validate (kernel, filelen)) |
|
400 |
++ { |
|
401 |
++ grub_error (GRUB_ERR_ACCESS_DENIED, N_("%s has invalid signature"), argv[0]); |
|
402 |
++ grub_free (kernel); |
|
403 |
++ goto fail; |
|
404 |
++ } |
|
405 |
++ |
|
406 |
++ grub_file_seek (file, 0); |
|
407 |
++ |
|
408 |
++ grub_free(kernel); |
|
409 |
++ |
|
410 |
++ params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); |
|
411 |
++ |
|
412 |
++ if (! params) |
|
413 |
++ { |
|
414 |
++ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); |
|
415 |
++ goto fail; |
|
416 |
++ } |
|
417 |
++ |
|
418 |
++ memset (params, 0, 16384); |
|
419 |
++ |
|
420 |
++ if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) |
|
421 |
++ { |
|
422 |
++ if (!grub_errno) |
|
423 |
++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), |
|
424 |
++ argv[0]); |
|
425 |
++ goto fail; |
|
426 |
++ } |
|
427 |
++ |
|
428 |
++ if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) |
|
429 |
++ { |
|
430 |
++ grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number")); |
|
431 |
++ goto fail; |
|
432 |
++ } |
|
433 |
++ |
|
434 |
++ if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) |
|
435 |
++ { |
|
436 |
++ grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors")); |
|
437 |
++ goto fail; |
|
438 |
++ } |
|
439 |
++ |
|
440 |
++ if (lh.version < grub_cpu_to_le16 (0x020b)) |
|
441 |
++ { |
|
442 |
++ grub_error (GRUB_ERR_BAD_OS, N_("kernel too old")); |
|
443 |
++ goto fail; |
|
444 |
++ } |
|
445 |
++ |
|
446 |
++ if (!lh.handover_offset) |
|
447 |
++ { |
|
448 |
++ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover")); |
|
449 |
++ goto fail; |
|
450 |
++ } |
|
451 |
++ |
|
452 |
++ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, |
|
453 |
++ BYTES_TO_PAGES(lh.cmdline_size + 1)); |
|
454 |
++ |
|
455 |
++ if (!linux_cmdline) |
|
456 |
++ { |
|
457 |
++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); |
|
458 |
++ goto fail; |
|
459 |
++ } |
|
460 |
++ |
|
461 |
++ grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); |
|
462 |
++ grub_create_loader_cmdline (argc, argv, |
|
463 |
++ linux_cmdline + sizeof (LINUX_IMAGE) - 1, |
|
464 |
++ lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1)); |
|
465 |
++ |
|
466 |
++ lh.cmd_line_ptr = (grub_uint32_t)(grub_uint64_t)linux_cmdline; |
|
467 |
++ |
|
468 |
++ handover_offset = lh.handover_offset; |
|
469 |
++ |
|
470 |
++ start = (lh.setup_sects + 1) * 512; |
|
471 |
++ len = grub_file_size(file) - start; |
|
472 |
++ |
|
473 |
++ kernel_mem = grub_efi_allocate_pages(lh.pref_address, |
|
474 |
++ BYTES_TO_PAGES(lh.init_size)); |
|
475 |
++ |
|
476 |
++ if (!kernel_mem) |
|
477 |
++ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, |
|
478 |
++ BYTES_TO_PAGES(lh.init_size)); |
|
479 |
++ |
|
480 |
++ if (!kernel_mem) |
|
481 |
++ { |
|
482 |
++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); |
|
483 |
++ goto fail; |
|
484 |
++ } |
|
485 |
++ |
|
486 |
++ if (grub_file_seek (file, start) == (grub_off_t) -1) |
|
487 |
++ { |
|
488 |
++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), |
|
489 |
++ argv[0]); |
|
490 |
++ goto fail; |
|
491 |
++ } |
|
492 |
++ |
|
493 |
++ if (grub_file_read (file, kernel_mem, len) != len && !grub_errno) |
|
494 |
++ { |
|
495 |
++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), |
|
496 |
++ argv[0]); |
|
497 |
++ } |
|
498 |
++ |
|
499 |
++ if (grub_errno == GRUB_ERR_NONE) |
|
500 |
++ { |
|
501 |
++ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); |
|
502 |
++ loaded = 1; |
|
503 |
++ lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; |
|
504 |
++ } |
|
505 |
++ |
|
506 |
++ memcpy(params, &lh, 2 * 512); |
|
507 |
++ |
|
508 |
++ params->type_of_loader = 0x21; |
|
509 |
++ |
|
510 |
++ fail: |
|
511 |
++ fail_errno = grub_errno; |
|
512 |
++ if (file) |
|
513 |
++ grub_file_close (file); |
|
514 |
++ |
|
515 |
++ if (fail_errno != GRUB_ERR_NONE) |
|
516 |
++ { |
|
517 |
++ grub_dl_unref (my_mod); |
|
518 |
++ loaded = 0; |
|
519 |
++ } |
|
520 |
++ |
|
521 |
++ if (linux_cmdline && !loaded) |
|
522 |
++ grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1)); |
|
523 |
++ |
|
524 |
++ if (kernel_mem && !loaded) |
|
525 |
++ grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); |
|
526 |
++ |
|
527 |
++ if (params && !loaded) |
|
528 |
++ grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); |
|
529 |
++ |
|
530 |
++ return fail_errno; |
|
531 |
++} |
|
532 |
++ |
|
533 |
++static grub_command_t cmd_linux, cmd_initrd; |
|
534 |
++ |
|
535 |
++GRUB_MOD_INIT(linuxefi) |
|
536 |
++{ |
|
537 |
++ cmd_linux = |
|
538 |
++ grub_register_command ("linuxefi", grub_cmd_linux, |
|
539 |
++ 0, N_("Load Linux.")); |
|
540 |
++ cmd_initrd = |
|
541 |
++ grub_register_command ("initrdefi", grub_cmd_initrd, |
|
542 |
++ 0, N_("Load initrd.")); |
|
543 |
++ my_mod = mod; |
|
544 |
++} |
|
545 |
++ |
|
546 |
++GRUB_MOD_FINI(linuxefi) |
|
547 |
++{ |
|
548 |
++ grub_unregister_command (cmd_linux); |
|
549 |
++ grub_unregister_command (cmd_initrd); |
|
550 |
++} |
|
551 |
+diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c |
|
552 |
+index b15b8cc..fce1b45 100644 |
|
553 |
+--- a/grub-core/loader/i386/linux.c |
|
554 |
+@@ -75,6 +75,8 @@ static grub_size_t maximal_cmdline_size; |
|
555 |
+ static struct linux_kernel_params linux_params; |
|
556 |
+ static char *linux_cmdline; |
|
557 |
+ #ifdef GRUB_MACHINE_EFI |
|
558 |
++static int using_linuxefi; |
|
559 |
++static grub_command_t initrdefi_cmd; |
|
560 |
+ static grub_efi_uintn_t efi_mmap_size; |
|
561 |
+ #else |
|
562 |
+ static const grub_size_t efi_mmap_size = 0; |
|
563 |
+@@ -689,6 +691,43 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
|
564 |
+ |
|
565 |
+ grub_dl_ref (my_mod); |
|
566 |
+ |
|
567 |
++#ifdef GRUB_MACHINE_EFI |
|
568 |
++ using_linuxefi = 0; |
|
569 |
++ if (grub_efi_secure_boot ()) |
|
570 |
++ { |
|
571 |
++ /* Use linuxefi if SB is enabled, which will require a successful |
|
572 |
++ signature check and then hand over to the kernel without calling |
|
573 |
++ ExitBootServices. |
|
574 |
++ If that fails, however, DO NOT fall back to original 'linux' |
|
575 |
++ command which boots an unsigned kernel. */ |
|
576 |
++ grub_dl_t mod; |
|
577 |
++ grub_command_t linuxefi_cmd; |
|
578 |
++ |
|
579 |
++ grub_dprintf ("linux", "Secure Boot enabled: trying linuxefi\n"); |
|
580 |
++ |
|
581 |
++ mod = grub_dl_load ("linuxefi"); |
|
582 |
++ if (mod) |
|
583 |
++ { |
|
584 |
++ grub_dl_ref (mod); |
|
585 |
++ linuxefi_cmd = grub_command_find ("linuxefi"); |
|
586 |
++ initrdefi_cmd = grub_command_find ("initrdefi"); |
|
587 |
++ if (linuxefi_cmd && initrdefi_cmd) |
|
588 |
++ { |
|
589 |
++ (linuxefi_cmd->func) (linuxefi_cmd, argc, argv); |
|
590 |
++ if (grub_errno == GRUB_ERR_NONE) |
|
591 |
++ { |
|
592 |
++ grub_dprintf ("linux", "Handing off to linuxefi\n"); |
|
593 |
++ using_linuxefi = 1; |
|
594 |
++ return GRUB_ERR_NONE; |
|
595 |
++ } |
|
596 |
++ grub_dprintf ("linux", "linuxefi failed (%d)\n", grub_errno); |
|
597 |
++ grub_errno = GRUB_ERR_ACCESS_DENIED; |
|
598 |
++ } |
|
599 |
++ } |
|
600 |
++ goto fail; |
|
601 |
++ } |
|
602 |
++#endif |
|
603 |
++ |
|
604 |
+ if (argc == 0) |
|
605 |
+ { |
|
606 |
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); |
|
607 |
+@@ -1051,6 +1090,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), |
|
608 |
+ grub_err_t err; |
|
609 |
+ struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; |
|
610 |
+ |
|
611 |
++#ifdef GRUB_MACHINE_EFI |
|
612 |
++ /* If we're using linuxefi, just forward to initrdefi. */ |
|
613 |
++ if (using_linuxefi && initrdefi_cmd) |
|
614 |
++ return (initrdefi_cmd->func) (initrdefi_cmd, argc, argv); |
|
615 |
++#endif |
|
616 |
++ |
|
617 |
+ if (argc == 0) |
|
618 |
+ { |
|
619 |
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); |
|
620 |
+diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h |
|
621 |
+index e9c601f..62a3d97 100644 |
|
622 |
+--- a/include/grub/efi/efi.h |
|
623 |
+@@ -40,6 +40,9 @@ void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds); |
|
624 |
+ void * |
|
625 |
+ EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address, |
|
626 |
+ grub_efi_uintn_t pages); |
|
627 |
++void * |
|
628 |
++EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max, |
|
629 |
++ grub_efi_uintn_t pages); |
|
630 |
+ void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, |
|
631 |
+ grub_efi_uintn_t pages); |
|
632 |
+ int |
|
633 |
+@@ -73,6 +76,7 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var, |
|
634 |
+ const grub_efi_guid_t *guid, |
|
635 |
+ void *data, |
|
636 |
+ grub_size_t datasize); |
|
637 |
++grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void); |
|
638 |
+ int |
|
639 |
+ EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, |
|
640 |
+ const grub_efi_device_path_t *dp2); |
|
641 |
+diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h |
|
642 |
+index da0ca3b..fc36bda 100644 |
|
643 |
+--- a/include/grub/i386/linux.h |
|
644 |
+@@ -139,6 +139,7 @@ struct linux_kernel_header |
|
645 |
+ grub_uint64_t setup_data; |
|
646 |
+ grub_uint64_t pref_address; |
|
647 |
+ grub_uint32_t init_size; |
|
648 |
++ grub_uint32_t handover_offset; |
|
649 |
+ } GRUB_PACKED; |
|
650 |
+ |
|
651 |
+ /* Boot parameters for Linux based on 2.6.12. This is used by the setup |
|
652 |
+-- |
|
653 |
+2.8.1 |
|
654 |
+ |
... | ... |
@@ -3,7 +3,7 @@ |
3 | 3 |
Summary: GRand Unified Bootloader |
4 | 4 |
Name: grub2 |
5 | 5 |
Version: 2.02 |
6 |
-Release: 8%{?dist} |
|
6 |
+Release: 9%{?dist} |
|
7 | 7 |
License: GPLv3+ |
8 | 8 |
URL: http://www.gnu.org/software/grub |
9 | 9 |
Group: Applications/System |
... | ... |
@@ -12,6 +12,7 @@ Distribution: Photon |
12 | 12 |
Source0: http://alpha.gnu.org/gnu/grub/grub-2.02~rc2.tar.xz |
13 | 13 |
%define sha1 grub=4f6f3719fd7dbb0449a58547c1b08c9801337663 |
14 | 14 |
Patch0: Fix_to_boot_entries_with_out_password.patch |
15 |
+Patch1: 0001-Secure-Boot-support.patch |
|
15 | 16 |
BuildRequires: device-mapper-devel |
16 | 17 |
BuildRequires: xz-devel |
17 | 18 |
BuildRequires: systemd-devel |
... | ... |
@@ -23,28 +24,73 @@ The GRUB package contains the GRand Unified Bootloader. |
23 | 23 |
%package lang |
24 | 24 |
Summary: Additional language files for grub |
25 | 25 |
Group: System Environment/Programming |
26 |
-Requires: grub2 >= 2.00 |
|
26 |
+Requires: %{name} = %{version} |
|
27 | 27 |
%description lang |
28 | 28 |
These are the additional language files of grub. |
29 | 29 |
|
30 |
+%package pc |
|
31 |
+Summary: GRUB Library for BIOS |
|
32 |
+Group: System Environment/Programming |
|
33 |
+Requires: %{name} = %{version} |
|
34 |
+%description pc |
|
35 |
+Additional library files for grub |
|
36 |
+ |
|
37 |
+%package efi |
|
38 |
+Summary: GRUB Library for UEFI |
|
39 |
+Group: System Environment/Programming |
|
40 |
+Requires: %{name} = %{version} |
|
41 |
+%description efi |
|
42 |
+Additional library files for grub |
|
30 | 43 |
|
31 | 44 |
%prep |
32 | 45 |
%setup -qn grub-2.02~rc2 |
33 | 46 |
%patch0 -p1 |
47 |
+%patch1 -p1 |
|
34 | 48 |
%build |
35 |
-./configure \ |
|
49 |
+./autogen.sh |
|
50 |
+mkdir build-for-pc build-for-efi |
|
51 |
+cd build-for-pc |
|
52 |
+../configure \ |
|
36 | 53 |
--prefix=%{_prefix} \ |
37 | 54 |
--sbindir=/sbin \ |
38 | 55 |
--sysconfdir=%{_sysconfdir} \ |
39 | 56 |
--disable-grub-emu-usb \ |
57 |
+ --disable-werror \ |
|
40 | 58 |
--disable-efiemu \ |
59 |
+ --with-grubdir=grub2 \ |
|
60 |
+ --with-platform=pc \ |
|
61 |
+ --target=i386 \ |
|
62 |
+ --program-transform-name=s,grub,%{name}, \ |
|
63 |
+ --with-bootdir="/boot" |
|
64 |
+make %{?_smp_mflags} |
|
65 |
+make DESTDIR=$PWD/../install-for-pc install |
|
66 |
+cd ../build-for-efi |
|
67 |
+../configure \ |
|
68 |
+ --prefix=%{_prefix} \ |
|
69 |
+ --sbindir=/sbin \ |
|
70 |
+ --sysconfdir=%{_sysconfdir} \ |
|
71 |
+ --disable-grub-emu-usb \ |
|
41 | 72 |
--disable-werror \ |
73 |
+ --disable-efiemu \ |
|
74 |
+ --with-grubdir=grub2 \ |
|
75 |
+ --with-platform=efi \ |
|
76 |
+ --target=x86_64 \ |
|
42 | 77 |
--program-transform-name=s,grub,%{name}, \ |
43 |
- --with-grubdir=%{name} |
|
78 |
+ --with-bootdir="/boot" |
|
44 | 79 |
make %{?_smp_mflags} |
80 |
+make DESTDIR=$PWD/../install-for-efi install |
|
81 |
+ |
|
82 |
+#make sure all the files are same between two configure except the /usr/lib/grub |
|
83 |
+%check |
|
84 |
+diff -sr install-for-efi/sbin install-for-pc/sbin && \ |
|
85 |
+diff -sr install-for-efi%{_bindir} install-for-pc%{_bindir} && \ |
|
86 |
+diff -sr install-for-efi%{_sysconfdir} install-for-pc%{_sysconfdir} && \ |
|
87 |
+diff -sr install-for-efi%{_datarootdir} install-for-pc%{_datarootdir} |
|
45 | 88 |
|
46 | 89 |
%install |
47 |
-make DESTDIR=%{buildroot} install |
|
90 |
+mkdir -p %{buildroot} |
|
91 |
+cp -a install-for-efi/. %{buildroot}/. |
|
92 |
+cp -a install-for-pc/. %{buildroot}/. |
|
48 | 93 |
mkdir %{buildroot}%{_sysconfdir}/default |
49 | 94 |
touch %{buildroot}%{_sysconfdir}/default/grub |
50 | 95 |
mkdir %{buildroot}%{_sysconfdir}/sysconfig |
... | ... |
@@ -52,8 +98,10 @@ ln -sf %{_sysconfdir}/default/grub %{buildroot}%{_sysconfdir}/sysconfig/grub |
52 | 52 |
mkdir -p %{buildroot}/boot/%{name} |
53 | 53 |
touch %{buildroot}/boot/%{name}/grub.cfg |
54 | 54 |
rm -rf %{buildroot}%{_infodir} |
55 |
+ |
|
55 | 56 |
%post -p /sbin/ldconfig |
56 | 57 |
%postun -p /sbin/ldconfig |
58 |
+ |
|
57 | 59 |
%files |
58 | 60 |
%defattr(-,root,root) |
59 | 61 |
%dir %{_sysconfdir}/grub.d |
... | ... |
@@ -62,22 +110,29 @@ rm -rf %{buildroot}%{_infodir} |
62 | 62 |
%config() %{_sysconfdir}/grub.d/10_linux |
63 | 63 |
%config() %{_sysconfdir}/grub.d/20_linux_xen |
64 | 64 |
%config() %{_sysconfdir}/grub.d/30_os-prober |
65 |
-%config() %{_sysconfdir}/grub.d/40_custom |
|
66 |
-%config() %{_sysconfdir}/grub.d/41_custom |
|
67 |
-%config() %{_sysconfdir}/grub.d/README |
|
65 |
+%config(noreplace) %{_sysconfdir}/grub.d/40_custom |
|
66 |
+%config(noreplace) %{_sysconfdir}/grub.d/41_custom |
|
67 |
+%{_sysconfdir}/grub.d/README |
|
68 | 68 |
/sbin/* |
69 | 69 |
%{_bindir}/* |
70 |
-%{_libdir}/grub/* |
|
71 | 70 |
%{_datarootdir}/grub/* |
72 | 71 |
%{_sysconfdir}/sysconfig/grub |
73 | 72 |
%{_sysconfdir}/default/grub |
74 | 73 |
%ghost %config(noreplace) /boot/%{name}/grub.cfg |
75 | 74 |
|
75 |
+%files pc |
|
76 |
+%{_libdir}/grub/i386-pc |
|
77 |
+ |
|
78 |
+%files efi |
|
79 |
+%{_libdir}/grub/x86_64-efi |
|
80 |
+ |
|
76 | 81 |
%files lang |
77 | 82 |
%defattr(-,root,root) |
78 |
-/usr/share/locale/* |
|
83 |
+%{_datarootdir}/locale/* |
|
79 | 84 |
|
80 | 85 |
%changelog |
86 |
+* Fri Jun 2 2017 Bo Gan <ganb@vmware.com> 2.02-9 |
|
87 |
+- Split grub2 to grub2 and grub2-pc, remove grub2-efi spec |
|
81 | 88 |
* Fri Apr 14 2017 Alexey Makhalov <amakhalov@vmware.com> 2.02-8 |
82 | 89 |
- Version update to 2.02~rc2 |
83 | 90 |
* Fri Nov 18 2016 Anish Swaminathan <anishs@vmware.com> 2.02-7 |
... | ... |
@@ -5,5 +5,5 @@ |
5 | 5 |
"libffi","expat","linux","cpio","Linux-PAM","attr","libcap", "systemd","dbus", |
6 | 6 |
"gzip", "sqlite","nspr","nss","popt","lua","rpm","gptfdisk","tar", "librepo", |
7 | 7 |
"hawkey", "python2","python2-libs","pcre","glib", "tdnf", "python-requests", |
8 |
- "grub2", "dracut", "curl", "ostree", "dosfstools"] |
|
8 |
+ "grub2-pc", "grub2-efi", "dracut", "curl", "ostree", "dosfstools"] |
|
9 | 9 |
} |