From: Jeremy Szu Date: Sun, 4 Dec 2022 12:25:09 +0000 (+0800) Subject: loader/i386/linux: Fix initrd maximum address overflow X-Git-Tag: grub-2.12-rc1~194 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=012fe7f0550899a2f1cf2fcf48f29ecf4820f880;p=thirdparty%2Fgrub.git loader/i386/linux: Fix initrd maximum address overflow The current i386 initrd is limited under 1 GiB memory and it works with most compressed initrds (also initrd_addr_max case reported by kernel). addr = (addr_max - aligned_size) & ~0xFFF; Above line is used to calculate the reasonable address to store the initrd. However, if initrd size is greater than 1 GiB or initrd_addr_max, then it will get overflow, especially on x86_64 arch. Therefore, add a check point to prevent it overflows as well as having a debug log for complex story of initrd addresses. Signed-off-by: Jeremy Szu Reviewed-by: Daniel Kiper --- diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index edd6c2bb1..10a367629 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -1085,9 +1085,22 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), addr_min = (grub_addr_t) prot_mode_target + prot_init_space; + /* Make sure the maximum address is able to store the initrd. */ + if (addr_max < aligned_size) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("the size of initrd is bigger than addr_max")); + goto fail; + } + /* Put the initrd as high as possible, 4KiB aligned. */ addr = (addr_max - aligned_size) & ~0xFFF; + grub_dprintf ("linux", + "Initrd at addr 0x%" PRIxGRUB_ADDR " which is expected in" + " ranger 0x%" PRIxGRUB_ADDR " ~ 0x%" PRIxGRUB_ADDR "\n", + addr, addr_min, addr_max); + if (addr < addr_min) { grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big");