From b9b17598f42c29b905a8b4a778e505244a89bd9a Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 4 Dec 2017 18:03:03 +0100 Subject: [PATCH] efi_loader: error handling in efi_load_image() If a failure occurs when trying to load an image, it is insufficient to free() the EFI object. We must remove it from the object list, too. Otherwise a use after free will occur the next time we iterate over the object list. Furthermore errors in setting up the image should be handled. Signed-off-by: Heinrich Schuchardt Signed-off-by: Alexander Graf --- lib/efi_loader/efi_boottime.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 7c8f3134d1..b90bd0b426 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1308,6 +1308,7 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, { struct efi_loaded_image *info; struct efi_object *obj; + efi_status_t ret; EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy, parent_image, file_path, source_buffer, source_size, image_handle); @@ -1317,41 +1318,39 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, if (!source_buffer) { struct efi_device_path *dp, *fp; - efi_status_t ret; ret = efi_load_image_from_path(file_path, &source_buffer); - if (ret != EFI_SUCCESS) { - free(info); - free(obj); - return EFI_EXIT(ret); - } - + if (ret != EFI_SUCCESS) + goto failure; /* * split file_path which contains both the device and * file parts: */ efi_dp_split_file_path(file_path, &dp, &fp); - - efi_setup_loaded_image(info, obj, dp, fp); + ret = efi_setup_loaded_image(info, obj, dp, fp); + if (ret != EFI_SUCCESS) + goto failure; } else { /* In this case, file_path is the "device" path, ie. * something like a HARDWARE_DEVICE:MEMORY_MAPPED */ - efi_setup_loaded_image(info, obj, file_path, NULL); + ret = efi_setup_loaded_image(info, obj, file_path, NULL); + if (ret != EFI_SUCCESS) + goto failure; } - info->reserved = efi_load_pe(source_buffer, info); if (!info->reserved) { - free(info); - free(obj); - return EFI_EXIT(EFI_UNSUPPORTED); + ret = EFI_UNSUPPORTED; + goto failure; } - info->system_table = &systab; info->parent_handle = parent_image; *image_handle = obj->handle; - return EFI_EXIT(EFI_SUCCESS); +failure: + free(info); + efi_delete_handle(obj); + return EFI_EXIT(ret); } /*