From caf864e434b3f12bae0c7e5932045ff8c9383180 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 6 Nov 2017 21:17:49 +0100 Subject: [PATCH] efi_loader: rework efi_locate_handle Check the parameters in efi_locate_handle. Use list_for_each_entry instead of list_for_each. Signed-off-by: Heinrich Schuchardt Signed-off-by: Alexander Graf --- lib/efi_loader/efi_boottime.c | 44 +++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 5bf26114a1..fdbdfc4670 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -896,6 +896,7 @@ static int efi_search(enum efi_locate_search_type search_type, case ALL_HANDLES: return 0; case BY_REGISTER_NOTIFY: + /* RegisterProtocolNotify is not implemented yet */ return -1; case BY_PROTOCOL: for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) { @@ -927,16 +928,38 @@ static efi_status_t efi_locate_handle( const efi_guid_t *protocol, void *search_key, efi_uintn_t *buffer_size, efi_handle_t *buffer) { - struct list_head *lhandle; + struct efi_object *efiobj; efi_uintn_t size = 0; + /* Check parameters */ + switch (search_type) { + case ALL_HANDLES: + break; + case BY_REGISTER_NOTIFY: + if (!search_key) + return EFI_INVALID_PARAMETER; + /* RegisterProtocolNotify is not implemented yet */ + return EFI_UNSUPPORTED; + case BY_PROTOCOL: + if (!protocol) + return EFI_INVALID_PARAMETER; + break; + default: + return EFI_INVALID_PARAMETER; + } + + /* + * efi_locate_handle_buffer uses this function for + * the calculation of the necessary buffer size. + * So do not require a buffer for buffersize == 0. + */ + if (!buffer_size || (*buffer_size && !buffer)) + return EFI_INVALID_PARAMETER; + /* Count how much space we need */ - list_for_each(lhandle, &efi_obj_list) { - struct efi_object *efiobj; - efiobj = list_entry(lhandle, struct efi_object, link); - if (!efi_search(search_type, protocol, search_key, efiobj)) { + list_for_each_entry(efiobj, &efi_obj_list, link) { + if (!efi_search(search_type, protocol, search_key, efiobj)) size += sizeof(void*); - } } if (*buffer_size < size) { @@ -949,12 +972,9 @@ static efi_status_t efi_locate_handle( return EFI_NOT_FOUND; /* Then fill the array */ - list_for_each(lhandle, &efi_obj_list) { - struct efi_object *efiobj; - efiobj = list_entry(lhandle, struct efi_object, link); - if (!efi_search(search_type, protocol, search_key, efiobj)) { - *(buffer++) = efiobj->handle; - } + list_for_each_entry(efiobj, &efi_obj_list, link) { + if (!efi_search(search_type, protocol, search_key, efiobj)) + *buffer++ = efiobj->handle; } return EFI_SUCCESS; -- 2.39.2