From 77648c5c01c79a330075824ff695ecd185514edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= Date: Fri, 15 Feb 2019 15:55:53 -0800 Subject: [PATCH 34/35] fallback: Use a dynamic buffer when list var names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that we are iterating over all EFI variables to look for duplicate boot entries, we should use a dynamic buffer, so if the firmware tells us the buffer is too small for the next variable name we can re-allocate it to a big enough size. Signed-off-by: João Paulo Rechi Vita --- fallback.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/fallback.c b/fallback.c index feb15df5..801955c7 100644 --- a/fallback.c +++ b/fallback.c @@ -415,9 +415,12 @@ find_boot_option(EFI_DEVICE_PATH *dp, EFI_DEVICE_PATH *fulldp, cursor += DevicePathSize(dp); StrCpy((CHAR16 *)cursor, arguments); - CHAR16 varname[256]; EFI_STATUS efi_status; EFI_GUID vendor_guid = NullGuid; + UINTN buffer_size = 256 * sizeof(CHAR16); + CHAR16 *varname = AllocateZeroPool(buffer_size); + if (!varname) + return EFI_OUT_OF_RESOURCES; UINTN max_candidate_size = calc_masked_boot_option_size(size); CHAR8 *candidate = AllocateZeroPool(max_candidate_size); @@ -426,14 +429,22 @@ find_boot_option(EFI_DEVICE_PATH *dp, EFI_DEVICE_PATH *fulldp, return EFI_OUT_OF_RESOURCES; } - varname[0] = 0; while (1) { - UINTN varname_size = sizeof(varname); + UINTN varname_size = buffer_size; efi_status = gRT->GetNextVariableName(&varname_size, varname, &vendor_guid); if (EFI_ERROR(efi_status)) { - if (efi_status == EFI_BUFFER_TOO_SMALL) - VerbosePrint(L"Buffer too small for next variable name\n"); + if (efi_status == EFI_BUFFER_TOO_SMALL) { + VerbosePrint(L"Buffer too small for next variable name, re-allocating it to be %d bytes and retrying\n", + varname_size); + varname = ReallocatePool(varname, + buffer_size, + varname_size); + if (!varname) + return EFI_OUT_OF_RESOURCES; + buffer_size = varname_size; + continue; + } if (efi_status == EFI_DEVICE_ERROR) VerbosePrint(L"The next variable name could not be retrieved due to a hardware error\n"); @@ -487,6 +498,7 @@ find_boot_option(EFI_DEVICE_PATH *dp, EFI_DEVICE_PATH *fulldp, } FreePool(candidate); FreePool(data); + FreePool(varname); return efi_status; } -- 2.32.0