From caf6d2fd1a0c4c8eb2b8125c10a9d6bc37676e1a Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 4 Feb 2019 12:49:43 +0100 Subject: efi_loader: efi_dp_split_file_path() error handling If the path passed to efi_dp_split_file_path() does not contain a reference to a file it returns EFI_OUT_OF_RESOURCES. This does not properly indicate the kind of the problem that occurred. Return EFI_INVALID_PARAMETER instead. Update function description. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_device_path.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'lib/efi_loader') diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index d94982314a3..98c36e798f5 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -910,9 +910,17 @@ struct efi_device_path *efi_dp_from_mem(uint32_t memory_type, return start; } -/* - * Helper to split a full device path (containing both device and file - * parts) into it's constituent parts. +/** + * efi_dp_split_file_path() - split of relative file path from device path + * + * Given a device path indicating a file on a device, separate the device + * path in two: the device path of the actual device and the file path + * relative to this device. + * + * @full_path: device path including device and file path + * @device_path: path of the device + * @file_path: relative path of the file + * Return: status code */ efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path, struct efi_device_path **device_path, @@ -929,7 +937,7 @@ efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path, while (!EFI_DP_TYPE(p, MEDIA_DEVICE, FILE_PATH)) { p = efi_dp_next(p); if (!p) - return EFI_OUT_OF_RESOURCES; + return EFI_INVALID_PARAMETER; } fp = efi_dp_dup(p); if (!fp) -- cgit v1.2.3 From 95288b1e94dbc0af9be969d12e82bf593dfb9044 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 4 Feb 2019 21:24:35 +0100 Subject: efi_loader: comments for efi_file_from_path() Add more comments for efi_file_from_path(). Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_file.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'lib/efi_loader') diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c index 4b4422205dd..3a7323765bd 100644 --- a/lib/efi_loader/efi_file.c +++ b/lib/efi_loader/efi_file.c @@ -641,6 +641,12 @@ static const struct efi_file_handle efi_file_handle_protocol = { .flush = efi_file_flush, }; +/** + * efi_file_from_path() - open file via device path + * + * @fp: device path + * @return: EFI_FILE_PROTOCOL for the file or NULL + */ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp) { struct efi_simple_file_system_protocol *v; @@ -655,10 +661,14 @@ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp) if (ret != EFI_SUCCESS) return NULL; - /* skip over device-path nodes before the file path: */ + /* Skip over device-path nodes before the file path. */ while (fp && !EFI_DP_TYPE(fp, MEDIA_DEVICE, FILE_PATH)) fp = efi_dp_next(fp); + /* + * Step through the nodes of the directory path until the actual file + * node is reached which is the final node in the device path. + */ while (fp) { struct efi_device_path_file_path *fdp = container_of(fp, struct efi_device_path_file_path, dp); -- cgit v1.2.3 From 16112f9f4832761e6af6f5ddb74c77a107992cb7 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 6 Feb 2019 19:41:29 +0100 Subject: efi_loader: error handling in efi_setup_loaded_image() In case of an error we should set the returned pointers to NULL. This ensures that an illegal free does not occur even if the caller calls free() for the handles. If protocols cannot be installed, release all resources. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_boottime.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'lib/efi_loader') diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index f74f989e0ae..d69160a6c2c 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1497,15 +1497,18 @@ static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid, /** * efi_setup_loaded_image() - initialize a loaded image - * @info: loaded image info to be passed to the entry point of the image - * @obj: internal object associated with the loaded image - * @device_path: device path of the loaded image - * @file_path: file path of the loaded image * * Initialize a loaded_image_info and loaded_image_info object with correct * protocols, boot-device, etc. * - * Return: status code + * In case of an error *handle_ptr and *info_ptr are set to NULL and an error + * code is returned. + * + * @device_path: device path of the loaded image + * @file_path: file path of the loaded image + * @handle_ptr: handle of the loaded image + * @info_ptr: loaded image protocol + * Return: status code */ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path, struct efi_device_path *file_path, @@ -1513,8 +1516,12 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path, struct efi_loaded_image **info_ptr) { efi_status_t ret; - struct efi_loaded_image *info; - struct efi_loaded_image_obj *obj; + struct efi_loaded_image *info = NULL; + struct efi_loaded_image_obj *obj = NULL; + + /* In case of EFI_OUT_OF_RESOURCES avoid illegal free by caller. */ + *handle_ptr = NULL; + *info_ptr = NULL; info = calloc(1, sizeof(*info)); if (!info) @@ -1528,11 +1535,6 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path, /* Add internal object to object list */ efi_add_handle(&obj->header); - if (info_ptr) - *info_ptr = info; - if (handle_ptr) - *handle_ptr = obj; - info->revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; info->file_path = file_path; info->system_table = &systab; @@ -1578,9 +1580,16 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path, goto failure; #endif + if (info_ptr) + *info_ptr = info; + if (handle_ptr) + *handle_ptr = obj; + return ret; failure: printf("ERROR: Failure to install protocols for loaded image\n"); + efi_delete_handle(&obj->header); + free(info); return ret; } -- cgit v1.2.3 From 0e18f584de59a86aaf86bd328dbd16fbd0175b3d Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 24 Dec 2018 09:19:07 +0100 Subject: efi_loader: LoadImage: always allocate new pages If we want to properly unload images in Exit() the memory should always be allocated in the same way. As we allocate memory when reading from file we should do the same when the original image is in memory. A further patch will be needed to free the memory when Exit() is called. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_bootmgr.c | 2 +- lib/efi_loader/efi_boottime.c | 100 +++++++++++++++++++++++++++++------------- 2 files changed, 71 insertions(+), 31 deletions(-) (limited to 'lib/efi_loader') diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index a095df3f540..196116b5472 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -150,7 +150,7 @@ static void *try_load_entry(uint16_t n, struct efi_device_path **device_path, debug("%s: trying to load \"%ls\" from %pD\n", __func__, lo.label, lo.file_path); - ret = efi_load_image_from_path(lo.file_path, &image); + ret = efi_load_image_from_path(lo.file_path, &image, &size); if (ret != EFI_SUCCESS) goto error; diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index d69160a6c2c..b1c0007e5a3 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1595,50 +1595,72 @@ failure: /** * efi_load_image_from_path() - load an image using a file path - * @file_path: the path of the image to load - * @buffer: buffer containing the loaded image * - * Return: status code + * Read a file into a buffer allocated as EFI_BOOT_SERVICES_DATA. It is the + * callers obligation to update the memory type as needed. + * + * @file_path: the path of the image to load + * @buffer: buffer containing the loaded image + * @size: size of the loaded image + * Return: status code */ efi_status_t efi_load_image_from_path(struct efi_device_path *file_path, - void **buffer) + void **buffer, efi_uintn_t *size) { struct efi_file_info *info = NULL; struct efi_file_handle *f; static efi_status_t ret; + u64 addr; efi_uintn_t bs; + /* In case of failure nothing is returned */ + *buffer = NULL; + *size = 0; + + /* Open file */ f = efi_file_from_path(file_path); if (!f) return EFI_DEVICE_ERROR; + /* Get file size */ bs = 0; EFI_CALL(ret = f->getinfo(f, (efi_guid_t *)&efi_file_info_guid, &bs, info)); - if (ret == EFI_BUFFER_TOO_SMALL) { - info = malloc(bs); - EFI_CALL(ret = f->getinfo(f, (efi_guid_t *)&efi_file_info_guid, - &bs, info)); - } - if (ret != EFI_SUCCESS) + if (ret != EFI_BUFFER_TOO_SMALL) { + ret = EFI_DEVICE_ERROR; goto error; + } - ret = efi_allocate_pool(EFI_LOADER_DATA, info->file_size, buffer); - if (ret) + info = malloc(bs); + EFI_CALL(ret = f->getinfo(f, (efi_guid_t *)&efi_file_info_guid, &bs, + info)); + if (ret != EFI_SUCCESS) goto error; + /* + * When reading the file we do not yet know if it contains an + * application, a boottime driver, or a runtime driver. So here we + * allocate a buffer as EFI_BOOT_SERVICES_DATA. The caller has to + * update the reservation according to the image type. + */ bs = info->file_size; - EFI_CALL(ret = f->read(f, &bs, *buffer)); - -error: - free(info); - EFI_CALL(f->close(f)); - + ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, + EFI_BOOT_SERVICES_DATA, + efi_size_in_pages(bs), &addr); if (ret != EFI_SUCCESS) { - efi_free_pool(*buffer); - *buffer = NULL; + ret = EFI_OUT_OF_RESOURCES; + goto error; } + /* Read file */ + EFI_CALL(ret = f->read(f, &bs, (void *)(uintptr_t)addr)); + if (ret != EFI_SUCCESS) + efi_free_pages(addr, efi_size_in_pages(bs)); + *buffer = (void *)(uintptr_t)addr; + *size = bs; +error: + EFI_CALL(f->close(f)); + free(info); return ret; } @@ -1665,6 +1687,7 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, efi_uintn_t source_size, efi_handle_t *image_handle) { + struct efi_device_path *dp, *fp; struct efi_loaded_image *info = NULL; struct efi_loaded_image_obj **image_obj = (struct efi_loaded_image_obj **)image_handle; @@ -1684,36 +1707,53 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, } if (!source_buffer) { - struct efi_device_path *dp, *fp; - - ret = efi_load_image_from_path(file_path, &source_buffer); + ret = efi_load_image_from_path(file_path, &source_buffer, + &source_size); if (ret != EFI_SUCCESS) - goto failure; + goto error; /* * split file_path which contains both the device and * file parts: */ efi_dp_split_file_path(file_path, &dp, &fp); - ret = efi_setup_loaded_image(dp, fp, image_obj, &info); - if (ret != EFI_SUCCESS) - goto failure; } else { /* In this case, file_path is the "device" path, i.e. * something like a HARDWARE_DEVICE:MEMORY_MAPPED */ - ret = efi_setup_loaded_image(file_path, NULL, image_obj, &info); + u64 addr; + void *dest_buffer; + + ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, + EFI_RUNTIME_SERVICES_CODE, + efi_size_in_pages(source_size), &addr); if (ret != EFI_SUCCESS) goto error; + dest_buffer = (void *)(uintptr_t)addr; + memcpy(dest_buffer, source_buffer, source_size); + source_buffer = dest_buffer; + + dp = file_path; + fp = NULL; } + ret = efi_setup_loaded_image(dp, fp, image_obj, &info); + if (ret != EFI_SUCCESS) + goto error_invalid_image; (*image_obj)->entry = efi_load_pe(*image_obj, source_buffer, info); if (!(*image_obj)->entry) { ret = EFI_UNSUPPORTED; - goto failure; + goto error_invalid_image; } + /* Update the type of the allocated memory */ + efi_add_memory_map((uintptr_t)source_buffer, + efi_size_in_pages(source_size), + info->image_code_type, false); info->system_table = &systab; info->parent_handle = parent_image; return EFI_EXIT(EFI_SUCCESS); -failure: +error_invalid_image: + /* The image is invalid. Release all associated resources. */ + efi_free_pages((uintptr_t)source_buffer, + efi_size_in_pages(source_size)); efi_delete_handle(*image_handle); *image_handle = NULL; free(info); -- cgit v1.2.3 From 8f7e2b2980a2d964db60a19a5d2ef8532caddf7d Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 26 Dec 2018 12:49:09 +0100 Subject: efi_loader: set entry point in efi_load_pe() Up to now efi_load_pe() returns the entry point or NULL in case of an error. This does not allow to return correct error codes from LoadImage(). Let efi_load_pe() return a status code and fill in the entry point in the corresponding field of the image object. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_boottime.c | 6 ++---- lib/efi_loader/efi_image_loader.c | 37 +++++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 20 deletions(-) (limited to 'lib/efi_loader') diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index b1c0007e5a3..155cdc5a239 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1738,11 +1738,9 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, ret = efi_setup_loaded_image(dp, fp, image_obj, &info); if (ret != EFI_SUCCESS) goto error_invalid_image; - (*image_obj)->entry = efi_load_pe(*image_obj, source_buffer, info); - if (!(*image_obj)->entry) { - ret = EFI_UNSUPPORTED; + ret = efi_load_pe(*image_obj, source_buffer, info); + if (ret != EFI_SUCCESS) goto error_invalid_image; - } /* Update the type of the allocated memory */ efi_add_memory_map((uintptr_t)source_buffer, efi_size_in_pages(source_size), diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index a18ce0a5705..b55c2840e86 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -193,13 +193,19 @@ static void efi_set_code_and_data_type( } } -/* +/** + * efi_load_pe() - relocate EFI binary + * * This function loads all sections from a PE binary into a newly reserved - * piece of memory. On successful load it then returns the entry point for - * the binary. Otherwise NULL. + * piece of memory. On success the entry point is returned as handle->entry. + * + * @handle: loaded image handle + * @efi: pointer to the EFI binary + * @loaded_image_info: loaded image protocol + * Return: status code */ -void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, - struct efi_loaded_image *loaded_image_info) +efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, + struct efi_loaded_image *loaded_image_info) { IMAGE_NT_HEADERS32 *nt; IMAGE_DOS_HEADER *dos; @@ -210,7 +216,6 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, const IMAGE_BASE_RELOCATION *rel; unsigned long rel_size; int rel_idx = IMAGE_DIRECTORY_ENTRY_BASERELOC; - void *entry; uint64_t image_base; uint64_t image_size; unsigned long virt_size = 0; @@ -219,13 +224,13 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, dos = efi; if (dos->e_magic != IMAGE_DOS_SIGNATURE) { printf("%s: Invalid DOS Signature\n", __func__); - return NULL; + return EFI_LOAD_ERROR; } nt = (void *) ((char *)efi + dos->e_lfanew); if (nt->Signature != IMAGE_NT_SIGNATURE) { printf("%s: Invalid NT Signature\n", __func__); - return NULL; + return EFI_LOAD_ERROR; } for (i = 0; machines[i]; i++) @@ -237,7 +242,7 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, if (!supported) { printf("%s: Machine type 0x%04x is not supported\n", __func__, nt->FileHeader.Machine); - return NULL; + return EFI_LOAD_ERROR; } /* Calculate upper virtual address boundary */ @@ -263,9 +268,9 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, if (!efi_reloc) { printf("%s: Could not allocate %lu bytes\n", __func__, virt_size); - return NULL; + return EFI_OUT_OF_RESOURCES; } - entry = efi_reloc + opt->AddressOfEntryPoint; + handle->entry = efi_reloc + opt->AddressOfEntryPoint; rel_size = opt->DataDirectory[rel_idx].Size; rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress; virt_size = ALIGN(virt_size, opt->SectionAlignment); @@ -279,16 +284,16 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, if (!efi_reloc) { printf("%s: Could not allocate %lu bytes\n", __func__, virt_size); - return NULL; + return EFI_OUT_OF_RESOURCES; } - entry = efi_reloc + opt->AddressOfEntryPoint; + handle->entry = efi_reloc + opt->AddressOfEntryPoint; rel_size = opt->DataDirectory[rel_idx].Size; rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress; virt_size = ALIGN(virt_size, opt->SectionAlignment); } else { printf("%s: Invalid optional header magic %x\n", __func__, nt->OptionalHeader.Magic); - return NULL; + return EFI_LOAD_ERROR; } /* Load sections into RAM */ @@ -306,7 +311,7 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, (unsigned long)image_base) != EFI_SUCCESS) { efi_free_pages((uintptr_t) efi_reloc, (virt_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT); - return NULL; + return EFI_LOAD_ERROR; } /* Flush cache */ @@ -320,5 +325,5 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, handle->reloc_base = efi_reloc; handle->reloc_size = virt_size; - return entry; + return EFI_SUCCESS; } -- cgit v1.2.3 From f69d63fae281ba98c3d063097cf4e95d17f3754d Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 26 Dec 2018 13:28:09 +0100 Subject: efi_loader: use efi_start_image() for bootefi Remove the duplicate code in efi_do_enter() and use efi_start_image() to start the image invoked by the bootefi command. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_boottime.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/efi_loader') diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 155cdc5a239..45ed36755f8 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1772,9 +1772,9 @@ error: * * Return: status code */ -static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, - efi_uintn_t *exit_data_size, - u16 **exit_data) +efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, + efi_uintn_t *exit_data_size, + u16 **exit_data) { struct efi_loaded_image_obj *image_obj = (struct efi_loaded_image_obj *)image_handle; -- cgit v1.2.3 From 914df75b0c97b6e9774025500c061231db1cc6b4 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 9 Feb 2019 14:10:39 +0100 Subject: efi_loader: fix EFI entry counting `bootefi selftest` fails on qemu-x86_defconfig if efi_selftest() is not invoked using EFI_CALL(). Likewise we call the entry point of EFI payloads with EFI_CALL(efi_start_image()). entry_count indicates if we are in U-Boot (1) or in EFI payload code (0). As we start in U-Boot code the initial value has to be 1. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_boottime.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/efi_loader') diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 45ed36755f8..bd8b8a17ae7 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -44,7 +44,8 @@ static bool efi_is_direct_boot = true; static volatile void *efi_gd, *app_gd; #endif -static int entry_count; +/* 1 if inside U-Boot code, 0 if inside EFI payload code */ +static int entry_count = 1; static int nesting_level; /* GUID of the device tree table */ const efi_guid_t efi_guid_fdt = EFI_FDT_GUID; -- cgit v1.2.3 From 1db561e11f2b6b6cd8f64035cc12b067dd6c1f91 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 16 Feb 2019 15:22:13 +0100 Subject: efi_loader: documentation of image loader - Add missing function descriptions. - Update existing function descriptions to match Sphinx style. - Add lib/efi_loader/efi_image_loader.c to the input files for Sphinx generated documentation. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_image_loader.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'lib/efi_loader') diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index b55c2840e86..cec17eabaa3 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -42,8 +42,8 @@ static int machines[] = { #endif 0 }; -/* - * Print information about a loaded image. +/** + * efi_print_image_info() - print information about a loaded image * * If the program counter is located within the image the offset to the base * address is shown. @@ -51,7 +51,7 @@ static int machines[] = { * @obj: EFI object * @image: loaded image * @pc: program counter (use NULL to suppress offset output) - * @return: status code + * Return: status code */ static efi_status_t efi_print_image_info(struct efi_loaded_image_obj *obj, struct efi_loaded_image *image, @@ -69,8 +69,8 @@ static efi_status_t efi_print_image_info(struct efi_loaded_image_obj *obj, return EFI_SUCCESS; } -/* - * Print information about all loaded images. +/** + * efi_print_image_infos() - print information about all loaded images * * @pc: program counter (use NULL to suppress offset output) */ @@ -90,6 +90,15 @@ void efi_print_image_infos(void *pc) } } +/** + * efi_loader_relocate() - relocate UEFI binary + * + * @rel: pointer to the relocation table + * @rel_size: size of the relocation table in bytes + * @efi_reloc: actual load address of the image + * @pref_address: preferred load address of the image + * Return: status code + */ static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel, unsigned long rel_size, void *efi_reloc, unsigned long pref_address) @@ -159,11 +168,12 @@ void __weak invalidate_icache_all(void) /* If the system doesn't support icache_all flush, cross our fingers */ } -/* - * Determine the memory types to be used for code and data. +/** + * efi_set_code_and_data_type() - determine the memory types to be used for code + * and data. * - * @loaded_image_info image descriptor - * @image_type field Subsystem of the optional header for + * @loaded_image_info: image descriptor + * @image_type: field Subsystem of the optional header for * Windows specific field */ static void efi_set_code_and_data_type( -- cgit v1.2.3 From 997fc12ec91eccf6b7485565864f3eb8ce74def2 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 16 Feb 2019 15:36:33 +0100 Subject: efi_loader: do not miss last relocation block If the last block in the relocation table contains only a single relocation, the current coding ignores it. Fix the determination of the end of the relocation table. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_image_loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/efi_loader') diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index cec17eabaa3..fe66e7b9ffe 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -111,7 +111,7 @@ static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel, return EFI_SUCCESS; end = (const IMAGE_BASE_RELOCATION *)((const char *)rel + rel_size); - while (rel < end - 1 && rel->SizeOfBlock) { + while (rel < end && rel->SizeOfBlock) { const uint16_t *relocs = (const uint16_t *)(rel + 1); i = (rel->SizeOfBlock - sizeof(*rel)) / sizeof(uint16_t); while (i--) { -- cgit v1.2.3