Skip to content

Commit 35c725e

Browse files
committed
efi/chainloader: support Secure Launch
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
1 parent 8537969 commit 35c725e

File tree

1 file changed

+56
-15
lines changed

1 file changed

+56
-15
lines changed

grub-core/loader/efi/chainloader.c

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <grub/command.h>
3737
#include <grub/i18n.h>
3838
#include <grub/net.h>
39+
#include <grub/slaunch.h>
3940
#if defined (__i386__) || defined (__x86_64__)
4041
#include <grub/macho.h>
4142
#include <grub/i386/macho.h>
@@ -45,13 +46,35 @@ GRUB_MOD_LICENSE ("GPLv3+");
4546

4647
static grub_dl_t my_mod;
4748

49+
static void *image_mem;
50+
static grub_efi_physical_address_t image_address;
51+
static grub_efi_uintn_t image_pages;
52+
53+
static struct grub_slaunch_params slparams = {0};
54+
55+
static void
56+
free_image (void)
57+
{
58+
if (image_address)
59+
{
60+
grub_efi_system_table->boot_services->free_pages (image_address,
61+
image_pages);
62+
63+
image_mem = NULL;
64+
image_address = 0;
65+
image_pages = 0;
66+
}
67+
}
68+
4869
static grub_err_t
4970
grub_chainloader_unload (void *context)
5071
{
5172
grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
5273
grub_efi_loaded_image_t *loaded_image;
5374
grub_efi_boot_services_t *b;
5475

76+
free_image ();
77+
5578
loaded_image = grub_efi_get_loaded_image (image_handle);
5679
if (loaded_image != NULL)
5780
grub_free (loaded_image->load_options);
@@ -71,6 +94,25 @@ grub_chainloader_boot (void *context)
7194
grub_efi_status_t status;
7295
grub_efi_uintn_t exit_data_size;
7396
grub_efi_char16_t *exit_data = NULL;
97+
grub_err_t err;
98+
grub_efi_loaded_image_t *loaded_image;
99+
100+
loaded_image = grub_efi_get_loaded_image (image_handle);
101+
if (loaded_image == NULL)
102+
return grub_error (GRUB_ERR_BUG, "Couldn't query EFI loaded image");
103+
104+
if (grub_slaunch_platform_type () == SLP_INTEL_TXT)
105+
{
106+
err = grub_sl_efi_txt_setup (&slparams, image_mem, loaded_image, /*is_linux=*/false);
107+
if (err != GRUB_ERR_NONE)
108+
return grub_error (err, "Secure Launch setup TXT failed");
109+
}
110+
else if (grub_slaunch_platform_type () == SLP_AMD_SKINIT)
111+
{
112+
err = grub_sl_efi_skinit_setup (&slparams, image_mem, loaded_image, /*is_linux=*/false);
113+
if (err != GRUB_ERR_NONE)
114+
return grub_error (err, "Secure Launch setup SKINIT failed");
115+
}
74116

75117
b = grub_efi_system_table->boot_services;
76118
status = b->start_image (image_handle, &exit_data_size, &exit_data);
@@ -220,17 +262,16 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
220262
grub_efi_device_path_t *dp = NULL, *file_path = NULL;
221263
grub_efi_loaded_image_t *loaded_image;
222264
char *filename;
223-
void *boot_image = 0;
224265
grub_efi_handle_t dev_handle = 0;
225-
grub_efi_physical_address_t address = 0;
226-
grub_efi_uintn_t pages = 0;
227266
grub_efi_char16_t *cmdline = NULL;
228267
grub_efi_handle_t image_handle = NULL;
229268

230269
if (argc == 0)
231270
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
232271
filename = argv[0];
233272

273+
free_image ();
274+
234275
grub_dl_ref (my_mod);
235276

236277
b = grub_efi_system_table->boot_services;
@@ -280,21 +321,21 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
280321
filename);
281322
goto fail;
282323
}
283-
pages = (grub_efi_uintn_t) GRUB_EFI_BYTES_TO_PAGES (size);
324+
image_pages = (grub_efi_uintn_t) GRUB_EFI_BYTES_TO_PAGES (size);
284325

285326
status = b->allocate_pages (GRUB_EFI_ALLOCATE_ANY_PAGES,
286327
GRUB_EFI_LOADER_CODE,
287-
pages, &address);
328+
image_pages, &image_address);
288329
if (status != GRUB_EFI_SUCCESS)
289330
{
290331
grub_dprintf ("chain", "Failed to allocate %u pages\n",
291-
(unsigned int) pages);
332+
(unsigned int) image_pages);
292333
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
293334
goto fail;
294335
}
295336

296-
boot_image = (void *) ((grub_addr_t) address);
297-
if (grub_file_read (file, boot_image, size) != size)
337+
image_mem = (void *) ((grub_addr_t) image_address);
338+
if (grub_file_read (file, image_mem, size) != size)
298339
{
299340
if (grub_errno == GRUB_ERR_NONE)
300341
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
@@ -306,7 +347,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
306347
#if defined (__i386__) || defined (__x86_64__)
307348
if (size >= (grub_ssize_t) sizeof (struct grub_macho_fat_header))
308349
{
309-
struct grub_macho_fat_header *head = boot_image;
350+
struct grub_macho_fat_header *head = image_mem;
310351
if (head->magic
311352
== grub_cpu_to_le32_compile_time (GRUB_MACHO_FAT_EFI_MAGIC))
312353
{
@@ -333,14 +374,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
333374
filename);
334375
goto fail;
335376
}
336-
boot_image = (char *) boot_image + grub_cpu_to_le32 (archs[i].offset);
377+
image_mem = (char *) image_mem + grub_cpu_to_le32 (archs[i].offset);
337378
size = grub_cpu_to_le32 (archs[i].size);
338379
}
339380
}
340381
#endif
341382

342383
status = b->load_image (0, grub_efi_image_handle, file_path,
343-
boot_image, size,
384+
image_mem, size,
344385
&image_handle);
345386
if (status != GRUB_EFI_SUCCESS)
346387
{
@@ -396,8 +437,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
396437
grub_file_close (file);
397438
grub_device_close (dev);
398439

399-
/* We're finished with the source image buffer and file path now. */
400-
b->free_pages (address, pages);
440+
/* We're typically finished with the source image buffer and file path here. */
441+
if (grub_slaunch_platform_type () == SLP_NONE)
442+
free_image ();
401443
grub_free (file_path);
402444

403445
grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, image_handle, 0);
@@ -414,8 +456,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
414456
grub_free (cmdline);
415457
grub_free (file_path);
416458

417-
if (address)
418-
b->free_pages (address, pages);
459+
free_image ();
419460

420461
if (image_handle != NULL)
421462
b->unload_image (image_handle);

0 commit comments

Comments
 (0)