From c7c0ca37673d8f1ae1c54dad1869101f566923f7 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 13 May 2023 10:36:21 +0200 Subject: efi_loader: fix efi_dp_from_file() * When called from efi_dp_from_name() we miss to append the filename for non-block devices. * expand_media_path() could be simplified by using efi_dp_from_file to prepend the device path of the boot device. This can be avoided by passing a device path to efi_dp_from_file() instead of a block device descriptor and a partition number. Signed-off-by: Heinrich Schuchardt --- cmd/bootefi.c | 2 +- include/efi_loader.h | 2 +- lib/efi_loader/efi_bootmgr.c | 13 +++++-------- lib/efi_loader/efi_device_path.c | 39 +++++++++++---------------------------- 4 files changed, 18 insertions(+), 38 deletions(-) diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 8aa15a64c8..5c0afec154 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -589,7 +589,7 @@ static efi_status_t bootefi_test_prepare if (!bootefi_device_path) return EFI_OUT_OF_RESOURCES; - bootefi_image_path = efi_dp_from_file(NULL, 0, path); + bootefi_image_path = efi_dp_from_file(NULL, path); if (!bootefi_image_path) { ret = EFI_OUT_OF_RESOURCES; goto failure; diff --git a/include/efi_loader.h b/include/efi_loader.h index b395eef9e7..38d7f66bab 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -810,7 +810,7 @@ bool efi_dp_is_multi_instance(const struct efi_device_path *dp); struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part); /* Create a device node for a block device partition. */ struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part); -struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part, +struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp, const char *path); struct efi_device_path *efi_dp_from_eth(void); struct efi_device_path *efi_dp_from_mem(uint32_t mem_type, diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 4b24b41047..7ac5f89f76 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -47,7 +47,7 @@ const efi_guid_t efi_guid_bootmenu_auto_generated = static struct efi_device_path *expand_media_path(struct efi_device_path *device_path) { - struct efi_device_path *dp, *rem, *full_path; + struct efi_device_path *rem, *full_path; efi_handle_t handle; if (!device_path) @@ -58,15 +58,12 @@ struct efi_device_path *expand_media_path(struct efi_device_path *device_path) * simple file system protocol, append a default file name to support * booting from removable media. */ - dp = device_path; - handle = efi_dp_find_obj(dp, &efi_simple_file_system_protocol_guid, - &rem); + handle = efi_dp_find_obj(device_path, + &efi_simple_file_system_protocol_guid, &rem); if (handle) { if (rem->type == DEVICE_PATH_TYPE_END) { - dp = efi_dp_from_file(NULL, 0, - "/EFI/BOOT/" BOOTEFI_NAME); - full_path = efi_dp_append(device_path, dp); - efi_free_pool(dp); + full_path = efi_dp_from_file(device_path, + "/EFI/BOOT/" BOOTEFI_NAME); } else { full_path = efi_dp_dup(device_path); } diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index a9b0ea4015..71923b1127 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -1002,47 +1002,31 @@ static void path_to_uefi(void *uefi, const char *src) } /** - * efi_dp_from_file() - create device path for file + * efi_dp_from_file() - append file path node to device path. * - * The function creates a device path from the block descriptor @desc and the - * partition number @part and appends a device path node created describing the - * file path @path. - * - * If @desc is NULL, the device path will not contain nodes describing the - * partition. - * If @path is an empty string "", the device path will not contain a node - * for the file path. - * - * @desc: block device descriptor or NULL - * @part: partition number - * @path: file path on partition or "" + * @dp: device path or NULL + * @path: file path or NULL * Return: device path or NULL in case of an error */ -struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part, - const char *path) +struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp, + const char *path) { struct efi_device_path_file_path *fp; void *buf, *pos; - size_t dpsize = 0, fpsize; - - if (desc) - dpsize = dp_part_size(desc, part); + size_t dpsize, fpsize; + dpsize = efi_dp_size(dp); fpsize = sizeof(struct efi_device_path) + 2 * (utf8_utf16_strlen(path) + 1); if (fpsize > U16_MAX) return NULL; - dpsize += fpsize; - - buf = efi_alloc(dpsize + sizeof(END)); + buf = efi_alloc(dpsize + fpsize + sizeof(END)); if (!buf) return NULL; - if (desc) - pos = dp_part_fill(buf, desc, part); - else - pos = buf; + memcpy(buf, dp, dpsize); + pos = buf + dpsize; /* add file-path: */ if (*path) { @@ -1218,8 +1202,7 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, if (!path) return EFI_SUCCESS; - *file = efi_dp_from_file(desc, part, path); - + *file = efi_dp_from_file(dp, path); if (!*file) return EFI_OUT_OF_RESOURCES; -- cgit v1.2.1