| From ed4f86e8b6eff8e600c69adee68c7cd34dd2cccb Mon Sep 17 00:00:00 2001 |
| From: Prasad J Pandit <pjp@fedoraproject.org> |
| Date: Thu, 7 Sep 2017 12:02:56 +0530 |
| Subject: [PATCH] multiboot: validate multiboot header address values |
| |
| While loading kernel via multiboot-v1 image, (flags & 0x00010000) |
| indicates that multiboot header contains valid addresses to load |
| the kernel image. These addresses are used to compute kernel |
| size and kernel text offset in the OS image. Validate these |
| address values to avoid an OOB access issue. |
| |
| This is CVE-2017-14167. |
| |
| Reported-by: Thomas Garnier <thgarnie@google.com> |
| Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> |
| Message-Id: <20170907063256.7418-1-ppandit@redhat.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| |
| Upstream-Status: Backport |
| [https://git.qemu.org/?p=qemu.git;a=commit;h=ed4f86e8b6eff8e600c69adee68c7cd34dd2cccb] |
| |
| CVE: CVE-2017-14167 |
| |
| Signed-off-by: Yi Zhao <yi.zhao@windriver.com> |
| --- |
| hw/i386/multiboot.c | 19 +++++++++++++++++++ |
| 1 file changed, 19 insertions(+) |
| |
| diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c |
| index 6001f4c..c7b70c9 100644 |
| --- a/hw/i386/multiboot.c |
| +++ b/hw/i386/multiboot.c |
| @@ -221,15 +221,34 @@ int load_multiboot(FWCfgState *fw_cfg, |
| uint32_t mh_header_addr = ldl_p(header+i+12); |
| uint32_t mh_load_end_addr = ldl_p(header+i+20); |
| uint32_t mh_bss_end_addr = ldl_p(header+i+24); |
| + |
| mh_load_addr = ldl_p(header+i+16); |
| + if (mh_header_addr < mh_load_addr) { |
| + fprintf(stderr, "invalid mh_load_addr address\n"); |
| + exit(1); |
| + } |
| + |
| uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr); |
| uint32_t mb_load_size = 0; |
| mh_entry_addr = ldl_p(header+i+28); |
| |
| if (mh_load_end_addr) { |
| + if (mh_bss_end_addr < mh_load_addr) { |
| + fprintf(stderr, "invalid mh_bss_end_addr address\n"); |
| + exit(1); |
| + } |
| mb_kernel_size = mh_bss_end_addr - mh_load_addr; |
| + |
| + if (mh_load_end_addr < mh_load_addr) { |
| + fprintf(stderr, "invalid mh_load_end_addr address\n"); |
| + exit(1); |
| + } |
| mb_load_size = mh_load_end_addr - mh_load_addr; |
| } else { |
| + if (kernel_file_size < mb_kernel_text_offset) { |
| + fprintf(stderr, "invalid kernel_file_size\n"); |
| + exit(1); |
| + } |
| mb_kernel_size = kernel_file_size - mb_kernel_text_offset; |
| mb_load_size = mb_kernel_size; |
| } |
| -- |
| 2.7.4 |
| |