Skip to content

Commit f9b8f78

Browse files
committed
grub-core/loader/efi/chainloader.c: clear free memory before loading image
This is meant to make measurements of DLME more deterministic in the face of firmware not bothering to zero area containing padding. Signed-off-by: Sergii Dmytruk <[email protected]>
1 parent 909d89d commit f9b8f78

File tree

1 file changed

+68
-1
lines changed

1 file changed

+68
-1
lines changed

grub-core/loader/efi/chainloader.c

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <grub/i18n.h>
3838
#include <grub/net.h>
3939
#include <grub/slaunch.h>
40+
#include <grub/time.h>
4041
#if defined (__i386__) || defined (__x86_64__)
4142
#include <grub/macho.h>
4243
#include <grub/i386/macho.h>
@@ -250,6 +251,57 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
250251
return file_path;
251252
}
252253

254+
/* Clear unused memory. This is meant to make measurements of DLME more
255+
* deterministic in the face of firmware not bothering to zero area containing
256+
* padding. */
257+
static grub_err_t
258+
clear_memory (void)
259+
{
260+
grub_efi_memory_descriptor_t *memory_map, *desc;
261+
grub_efi_uintn_t memory_map_size, desc_size;
262+
grub_efi_boot_services_t *b;
263+
grub_efi_uint64_t total_cleared = 0;
264+
int ret;
265+
266+
b = grub_efi_system_table->boot_services;
267+
268+
memory_map_size = grub_efi_find_mmap_size ();
269+
270+
memory_map = grub_malloc (memory_map_size);
271+
if (!memory_map)
272+
return GRUB_ERR_OUT_OF_MEMORY;
273+
274+
ret = grub_efi_get_memory_map (&memory_map_size, memory_map, NULL,
275+
&desc_size, NULL);
276+
if (ret < 1)
277+
return GRUB_ERR_BUG;
278+
279+
for (desc = memory_map;
280+
(grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size);
281+
desc = (void *)((grub_uint8_t *)desc + desc_size))
282+
{
283+
grub_efi_uint64_t size = desc->num_pages << 12;
284+
285+
if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY ||
286+
desc->physical_start >= (1ULL << 32))
287+
continue;
288+
289+
if (desc->physical_start + size > (1ULL << 32))
290+
size = (1ULL << 32) - desc->physical_start;
291+
292+
grub_dprintf ("chain", "Clearing %lu bytes at 0x%lx...\n", size,
293+
desc->physical_start);
294+
b->set_mem ((void *)desc->physical_start, size, 0x00);
295+
total_cleared += size;
296+
}
297+
298+
grub_free (memory_map);
299+
300+
grub_dprintf ("chain", "Cleared %llu bytes in total.\n",
301+
(unsigned long long)total_cleared);
302+
return GRUB_ERR_NONE;
303+
}
304+
253305
static grub_err_t
254306
grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
255307
int argc, char *argv[])
@@ -265,6 +317,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
265317
grub_efi_handle_t dev_handle = 0;
266318
grub_efi_char16_t *cmdline = NULL;
267319
grub_efi_handle_t image_handle = NULL;
320+
grub_uint64_t before_time, after_time;
321+
grub_err_t err;
268322

269323
if (argc == 0)
270324
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -291,7 +345,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
291345
grub_net_network_level_address_t addr;
292346
struct grub_net_network_level_interface *inf;
293347
grub_net_network_level_address_t gateway;
294-
grub_err_t err;
295348

296349
err = grub_net_resolve_address (dev->net->server, &addr);
297350
if (err)
@@ -344,6 +397,20 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
344397
goto fail;
345398
}
346399

400+
if (grub_slaunch_platform_type () != SLP_NONE)
401+
{
402+
before_time = grub_get_time_ms ();
403+
err = clear_memory();
404+
after_time = grub_get_time_ms ();
405+
grub_dprintf ("chain", "Took %llu ms to clear the memory\n",
406+
(unsigned long long)(after_time - before_time));
407+
if (err != GRUB_ERR_NONE)
408+
{
409+
grub_dprintf ("chain", "Failed to clear unused memory < 4 GiB\n");
410+
goto fail;
411+
}
412+
}
413+
347414
#if defined (__i386__) || defined (__x86_64__)
348415
if (size >= (grub_ssize_t) sizeof (struct grub_macho_fat_header))
349416
{

0 commit comments

Comments
 (0)