[PATCH 3/4] efi: loader: fix SizeOfBlock underflow in relocation processing
Sascha Hauer
s.hauer at pengutronix.de
Mon Apr 13 05:36:45 PDT 2026
From: Sascha Hauer <sascha at saschahauer.de>
rel->SizeOfBlock is a uint32_t read from the PE image. If it is smaller
than sizeof(IMAGE_BASE_RELOCATION) (8 bytes), the subtraction
SizeOfBlock - sizeof(*rel) underflows. On 32-bit architectures (ARM,
i386, riscv32) the resulting huge unsigned value divided by 2 fits in a
positive int, causing the relocation loop to iterate billions of times,
reading and writing far past the relocation block.
Reject relocation blocks with SizeOfBlock smaller than the base
relocation header.
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply at anthropic.com>
---
efi/loader/pe.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/efi/loader/pe.c b/efi/loader/pe.c
index 3190718df5..ea385c8795 100644
--- a/efi/loader/pe.c
+++ b/efi/loader/pe.c
@@ -120,6 +120,10 @@ static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
end = (const IMAGE_BASE_RELOCATION *)((const char *)rel + rel_size);
while (rel + 1 < end && rel->SizeOfBlock) {
const uint16_t *relocs = (const uint16_t *)(rel + 1);
+
+ if (rel->SizeOfBlock < sizeof(*rel))
+ return EFI_LOAD_ERROR;
+
i = (rel->SizeOfBlock - sizeof(*rel)) / sizeof(uint16_t);
while (i--) {
uint32_t offset = (uint32_t)(*relocs & 0xfff) +
--
2.47.3
More information about the barebox
mailing list