From 9537ddb0e7f2c080042d2c617d412197fa957a8d Mon Sep 17 00:00:00 2001 From: Alec Brown Date: Mon, 22 May 2023 16:52:46 -0400 Subject: [PATCH] loader/multiboot_elfxx: Check program memory isn't larger than allocated memory size In grub-core/loader/multiboot_elfxx.c, the code is filling an area of memory with grub_memset() but doesn't check if there is space in the allocated memory before doing so. To make sure we aren't zeroing memory past the allocated memory region, we need to check that the offset into the allocated memory region plus the memory size of the program is smaller than the allocated memory size. Fixes: CID 314029 Fixes: CID 314038 Signed-off-by: Alec Brown Reviewed-by: Daniel Kiper --- grub-core/loader/multiboot_elfxx.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c index e067d2d84..6f3516168 100644 --- a/grub-core/loader/multiboot_elfxx.c +++ b/grub-core/loader/multiboot_elfxx.c @@ -67,7 +67,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) char *phdr_base; grub_err_t err; grub_relocator_chunk_t ch; - grub_uint32_t load_offset = 0, load_size; + grub_uint32_t load_offset = 0, load_size = 0; Elf_Shnum shnum; Elf_Word shstrndx, phnum; unsigned int i; @@ -170,8 +170,9 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) } else { + load_size = phdr(i)->p_memsz; err = grub_relocator_alloc_chunk_addr (GRUB_MULTIBOOT (relocator), &ch, - phdr(i)->p_paddr, phdr(i)->p_memsz); + phdr(i)->p_paddr, load_size); if (err != GRUB_ERR_NONE) { @@ -199,8 +200,14 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) } if (phdr(i)->p_filesz < phdr(i)->p_memsz) - grub_memset ((grub_uint8_t *) source + load_offset + phdr(i)->p_filesz, 0, - phdr(i)->p_memsz - phdr(i)->p_filesz); + { + /* Need to insure that the memory being set isn't larger than the allocated memory. */ + if (load_offset + phdr(i)->p_memsz - phdr(i)->p_filesz > load_size) + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("memory being set is larger than allocated memory")); + + grub_memset ((grub_uint8_t *) source + load_offset + phdr(i)->p_filesz, 0, + phdr(i)->p_memsz - phdr(i)->p_filesz); + } } }