From f23883ccf78f1f605a272f9e5700f47e5494a71d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
Date: Mon, 16 Jan 2023 07:49:44 +0100
Subject: [PATCH] Don't loop forever in load_certs() with buggy firmware
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

On DELL R350 booting DVD through RFS with BIOS 1.4.2 in Secure Boot,
firmware returns EFI_BUFFER_TOO_SMALL but with new buffersize set to 0,
which causes the load_certs() code to loop forever:

while (1) {
    efi_status = dir->Read(dir, &buffersize, buffer);
    if (efi_status == EFI_BUFFER_TOO_SMALL) {
        ...
        continue;
    }
    ...
}

This commit prevents such infinite loop.

Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
---
 shim.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/shim.c b/shim.c
index 4437898..27a8c11 100644
--- a/shim.c
+++ b/shim.c
@@ -1483,11 +1483,21 @@ load_certs(EFI_HANDLE image_handle)
 	}
 
 	while (1) {
-		int old = buffersize;
+		UINTN old = buffersize;
 		efi_status = dir->Read(dir, &buffersize, buffer);
 		if (efi_status == EFI_BUFFER_TOO_SMALL) {
-			buffer = ReallocatePool(buffer, old, buffersize);
-			continue;
+			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);
+					goto done;
+				}
+				continue;
+			}
+			perror(L"Failed to read directory %s - buggy firmware\n",
+			       PathName);
+			goto done;
 		} else if (EFI_ERROR(efi_status)) {
 			perror(L"Failed to read directory %s - %r\n", PathName,
 			       efi_status);
-- 
2.27.0

