From 79a2b916a0dcfe37617caa1010a9f3778cd2fad5 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Sun, 29 May 2022 10:26:18 +0200 Subject: [PATCH] boot: Drop use of FileDevicePath --- src/boot/efi/boot.c | 6 +++--- src/boot/efi/drivers.c | 6 +++--- src/boot/efi/util.c | 37 +++++++++++++++++++++++++++++++++++++ src/boot/efi/util.h | 1 + 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index f00f004eaa..5287eabd6c 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -2349,9 +2349,9 @@ static EFI_STATUS image_start( if (err != EFI_SUCCESS) return log_error_status_stall(err, L"Error opening root path: %r", err); - path = FileDevicePath(entry->device, entry->loader); - if (!path) - return log_error_status_stall(EFI_INVALID_PARAMETER, L"Error getting device path."); + err = make_file_device_path(entry->device, entry->loader, &path); + if (err != EFI_SUCCESS) + return log_error_status_stall(err, L"Error making file device path: %r", err); UINTN initrd_size = 0; _cleanup_freepool_ void *initrd = NULL; diff --git a/src/boot/efi/drivers.c b/src/boot/efi/drivers.c index 65c74c461d..615c4ca1f3 100644 --- a/src/boot/efi/drivers.c +++ b/src/boot/efi/drivers.c @@ -21,9 +21,9 @@ static EFI_STATUS load_one_driver( assert(fname); spath = xpool_print(L"\\EFI\\systemd\\drivers\\%s", fname); - path = FileDevicePath(loaded_image->DeviceHandle, spath); - if (!path) - return log_oom(); + err = make_file_device_path(loaded_image->DeviceHandle, spath, &path); + if (err != EFI_SUCCESS) + return log_error_status_stall(err, L"Error making file device path: %r", err); err = BS->LoadImage(FALSE, parent_image, path, NULL, 0, &image); if (EFI_ERROR(err)) diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index 69bca420ae..c6324035ad 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -701,3 +701,40 @@ EFI_STATUS open_volume(EFI_HANDLE device, EFI_FILE **ret_file) { *ret_file = file; return EFI_SUCCESS; } + +EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DEVICE_PATH **ret_dp) { + EFI_STATUS err; + EFI_DEVICE_PATH *dp; + + assert(file); + assert(ret_dp); + + err = BS->HandleProtocol(device, &DevicePathProtocol, (void **) &dp); + if (err != EFI_SUCCESS) + return err; + + EFI_DEVICE_PATH *end_node = dp; + while (!IsDevicePathEnd(end_node)) + end_node = NextDevicePathNode(end_node); + + size_t file_size = strsize16(file); + size_t dp_size = ((uint8_t *) end_node - (uint8_t *) dp) + END_DEVICE_PATH_LENGTH; + + /* Make a copy that can also hold a file media device path. */ + *ret_dp = xmalloc(dp_size + file_size + SIZE_OF_FILEPATH_DEVICE_PATH); + memcpy(*ret_dp, dp, dp_size); + + /* Point dp to the end node of the copied device path. */ + dp = (EFI_DEVICE_PATH *) ((uint8_t *) *ret_dp + dp_size - END_DEVICE_PATH_LENGTH); + + /* Replace end node with file media device path. */ + FILEPATH_DEVICE_PATH *file_dp = (FILEPATH_DEVICE_PATH *) dp; + file_dp->Header.Type = MEDIA_DEVICE_PATH; + file_dp->Header.SubType = MEDIA_FILEPATH_DP; + memcpy(&file_dp->PathName, file, file_size); + SetDevicePathNodeLength(&file_dp->Header, SIZE_OF_FILEPATH_DEVICE_PATH + file_size); + + dp = NextDevicePathNode(dp); + SetDevicePathEndNode(dp); + return EFI_SUCCESS; +} diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index 8e28f5b1be..e191fe5866 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -187,3 +187,4 @@ static inline void beep(UINTN beep_count) {} #endif EFI_STATUS open_volume(EFI_HANDLE device, EFI_FILE **ret_file); +EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DEVICE_PATH **ret_dp); -- 2.25.1