multiboot: Reject kernels exceeding the address space
authorKevin Wolf <kwolf@redhat.com>
Wed, 14 Mar 2018 16:46:38 +0000 (17:46 +0100)
committerKevin Wolf <kwolf@redhat.com>
Wed, 21 Mar 2018 14:13:25 +0000 (15:13 +0100)
The code path where mh_load_end_addr is non-zero in the Multiboot
header checks that mh_load_end_addr >= mh_load_addr and so
mb_load_size is checked.  However, mb_load_size is not checked when
calculated from the file size, when mh_load_end_addr is 0.

If the kernel binary size is larger than can fit in the address space
after load_addr, we ended up with a kernel_size that is smaller than
load_size, which means that we read the file into a too small buffer.

Add a check to reject kernel files with such Multiboot headers.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Jack Schwartz <jack.schwartz@oracle.com>
hw/i386/multiboot.c

index b9064264d83564b1a8442523003b9d0f2a35e61b..1e215bf8d3833a9086b89617ca96e6b9a0d1cb92 100644 (file)
@@ -247,6 +247,10 @@ int load_multiboot(FWCfgState *fw_cfg,
             }
             mb_load_size = kernel_file_size - mb_kernel_text_offset;
         }
+        if (mb_load_size > UINT32_MAX - mh_load_addr) {
+            error_report("kernel does not fit in address space");
+            exit(1);
+        }
         if (mh_bss_end_addr) {
             if (mh_bss_end_addr < (mh_load_addr + mb_load_size)) {
                 error_report("invalid bss_end_addr address");