From: Ana Bobillo <[email protected]>
efi_check_pe() is meant to check that the image holds a 64bit NT header,
which is longer than a 32bit one, as its comment says. Since commit
5dad05a0e61d ("efi_loader: carve out efi_check_pe()") it checks for a
32bit one only, so the callers read the optional header fields and data
directories of a PE32+ image past the end of a truncated image. The
addition of e_lfanew can also wrap around on 32bit systems.
Check for the size of the 64bit NT header again, without wrapping.
Fixes: 5dad05a0e61d ("efi_loader: carve out efi_check_pe()")
Signed-off-by: Ana Bobillo <[email protected]>
---
lib/efi_loader/efi_image_loader.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_image_loader.c
b/lib/efi_loader/efi_image_loader.c
index f9a2d2df405..e31493d5135 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -849,7 +849,8 @@ efi_status_t efi_check_pe(void *buffer, size_t size, void
**nt_header)
* least one section header follows we only need to check for the length
* of the 64bit header which is longer than the 32bit header.
*/
- if (size < dos->e_lfanew + sizeof(IMAGE_NT_HEADERS32))
+ if (dos->e_lfanew > size ||
+ size - dos->e_lfanew < sizeof(IMAGE_NT_HEADERS64))
return EFI_INVALID_PARAMETER;
nt = (IMAGE_NT_HEADERS32 *)((u8 *)buffer + dos->e_lfanew);