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
4647static 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+
4869static grub_err_t
4970grub_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