summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPete Batard <pete@akeo.ie>2023-03-31 15:39:54 +0200
committerPeter Jones <pjones@redhat.com>2023-05-02 14:15:56 -0400
commitcf59f3452d478455c5f3d83790b37a372d2837ea (patch)
treee00758e04bf4bc999e6d1d6447517b2cd0aec660
parentcca3933f48e3a52863322f358c2e8cb8ea80bd57 (diff)
downloadefi-boot-shim-cf59f3452d478455c5f3d83790b37a372d2837ea.tar.gz
efi-boot-shim-cf59f3452d478455c5f3d83790b37a372d2837ea.zip
Further improve load_certs() for non-compliant drivers/firmwares
Following the discovery of more problematic firmwares and drivers affected by the issue f23883ccf78f1f605a272f9e5700f47e5494a71d is designed to address (e.g. https://github.com/rhboot/shim/issues/558), this patch further improves the code so that, instead of simply bailing out, we progressively increase the buffer sizes, until either success or a maximum size limit is reached. In most cases, this workaround should be enough to ensure completion of the directory read and thus provide full shim functionality (while still warning the user about the non-compliance of their environment). Signed-off-by: Pete Batard <pete@akeo.ie>
-rw-r--r--shim.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/shim.c b/shim.c
index b3a4fe6b..c31e97fb 100644
--- a/shim.c
+++ b/shim.c
@@ -1472,18 +1472,27 @@ load_certs(EFI_HANDLE image_handle)
UINTN old = buffersize;
efi_status = dir->Read(dir, &buffersize, buffer);
if (efi_status == EFI_BUFFER_TOO_SMALL) {
- if (buffersize != old) {
- buffer = ReallocatePool(buffer, old, buffersize);
- if (buffer == NULL) {
- perror(L"Failed to read directory %s - %r\n",
- PathName, EFI_OUT_OF_RESOURCES);
+ if (buffersize == old) {
+ /*
+ * Some UEFI drivers or firmwares are not compliant with
+ * the EFI_FILE_PROTOCOL.Read() specs and do not return the
+ * required buffer size along with EFI_BUFFER_TOO_SMALL.
+ * Work around this by progressively increasing the buffer
+ * size, up to a certain point, until the call succeeds.
+ */
+ perror(L"Error reading directory %s - non-compliant UEFI driver or firmware!\n",
+ PathName);
+ buffersize = (buffersize < 4) ? 4 : buffersize * 2;
+ if (buffersize > 1024)
goto done;
- }
- continue;
}
- perror(L"Failed to read directory %s - buggy firmware\n",
- PathName);
- goto done;
+ buffer = ReallocatePool(buffer, old, buffersize);
+ if (buffer == NULL) {
+ perror(L"Failed to read directory %s - %r\n",
+ PathName, EFI_OUT_OF_RESOURCES);
+ goto done;
+ }
+ continue;
} else if (EFI_ERROR(efi_status)) {
perror(L"Failed to read directory %s - %r\n", PathName,
efi_status);