efi/boot.c: add file.need_to_free

The config file, kernel, initrd, etc should only be freed if they
are allocated with the UEFI allocator.  On x86 the ucode, and on
ARM the dtb, are also marked as need_to_free when allocated or
expanded.

This also fixes a memory leak in ARM fdt_increase_size() if there
is an error in building the new device tree.

Signed-off-by: Trammell Hudson <hudson@trmm.net>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Trammell Hudson authored and Andrew Cooper committed 2020-10-09 17:20:11 +01:00
1 parent afef39241b
commit 04be2c3a06
3 files changed
+16 -7

No files matched your search

+9 -2
View File
@@ -314,7 +314,10 @@ static void __init *fdt_increase_size(struct file *fdtfile, int add_size)
if ( fdt_size )
{
if ( fdt_open_into(dtbfile.ptr, new_fdt, pages * EFI_PAGE_SIZE) )
{
efi_bs->FreePages(fdt_addr, pages);
return NULL;
}
}
else
{
@@ -326,7 +329,10 @@ static void __init *fdt_increase_size(struct file *fdtfile, int add_size)
* system table that is passed in the FDT.
*/
if ( fdt_create_empty_tree(new_fdt, pages * EFI_PAGE_SIZE) )
{
efi_bs->FreePages(fdt_addr, pages);
return NULL;
}
}
/*
@@ -335,12 +341,13 @@ static void __init *fdt_increase_size(struct file *fdtfile, int add_size)
* code will free it. If the original FDT came from a configuration
* table, we don't own that memory and can't free it.
*/
if ( dtbfile.size )
if ( dtbfile.need_to_free )
efi_bs->FreePages(dtbfile.addr, PFN_UP(dtbfile.size));
/* Update 'file' info for new memory so we clean it up on error exits */
dtbfile.addr = fdt_addr;
dtbfile.size = pages * EFI_PAGE_SIZE;
dtbfile.need_to_free = true;
return new_fdt;
}
@@ -546,7 +553,7 @@ static void __init efi_arch_cpu(void)
static void __init efi_arch_blexit(void)
{
if ( dtbfile.addr && dtbfile.size )
if ( dtbfile.need_to_free )
efi_bs->FreePages(dtbfile.addr, PFN_UP(dtbfile.size));
if ( memmap )
efi_bs->FreePool(memmap);
+1 -1
View File
@@ -689,7 +689,7 @@ static void __init efi_arch_cpu(void)
static void __init efi_arch_blexit(void)
{
if ( ucode.addr )
if ( ucode.need_to_free )
efi_bs->FreePages(ucode.addr, PFN_UP(ucode.size));
}
+6 -4
View File
@@ -102,6 +102,7 @@ union string {
struct file {
UINTN size;
bool need_to_free;
union {
EFI_PHYSICAL_ADDRESS addr;
char *str;
@@ -287,13 +288,13 @@ void __init noreturn blexit(const CHAR16 *str)
if ( !efi_bs )
efi_arch_halt();
if ( cfg.addr )
if ( cfg.need_to_free )
efi_bs->FreePages(cfg.addr, PFN_UP(cfg.size));
if ( kernel.addr )
if ( kernel.need_to_free )
efi_bs->FreePages(kernel.addr, PFN_UP(kernel.size));
if ( ramdisk.addr )
if ( ramdisk.need_to_free )
efi_bs->FreePages(ramdisk.addr, PFN_UP(ramdisk.size));
if ( xsm.addr )
if ( xsm.need_to_free )
efi_bs->FreePages(xsm.addr, PFN_UP(xsm.size));
efi_arch_blexit();
@@ -588,6 +589,7 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
}
else
{
file->need_to_free = true;
file->size = size;
if ( file != &cfg )
{
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.