]> git.proxmox.com Git - pve-qemu.git/blob - debian/patches/extra/0013-multiboot-validate-multiboot-header-address-values.patch
37d12aff022bc2cfea4b381a324fea0e2aa9ea45
[pve-qemu.git] / debian / patches / extra / 0013-multiboot-validate-multiboot-header-address-values.patch
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Prasad J Pandit <pjp@fedoraproject.org>
3 Date: Thu, 7 Sep 2017 12:02:56 +0530
4 Subject: [PATCH] multiboot: validate multiboot header address values
5
6 While loading kernel via multiboot-v1 image, (flags & 0x00010000)
7 indicates that multiboot header contains valid addresses to load
8 the kernel image. These addresses are used to compute kernel
9 size and kernel text offset in the OS image. Validate these
10 address values to avoid an OOB access issue.
11
12 This is CVE-2017-14167.
13
14 Reported-by: Thomas Garnier <thgarnie@google.com>
15 Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
16 ---
17 hw/i386/multiboot.c | 19 +++++++++++++++++++
18 1 file changed, 19 insertions(+)
19
20 diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
21 index f13e23139b..22688d376d 100644
22 --- a/hw/i386/multiboot.c
23 +++ b/hw/i386/multiboot.c
24 @@ -221,15 +221,34 @@ int load_multiboot(FWCfgState *fw_cfg,
25 uint32_t mh_header_addr = ldl_p(header+i+12);
26 uint32_t mh_load_end_addr = ldl_p(header+i+20);
27 uint32_t mh_bss_end_addr = ldl_p(header+i+24);
28 +
29 mh_load_addr = ldl_p(header+i+16);
30 + if (mh_header_addr < mh_load_addr) {
31 + fprintf(stderr, "invalid mh_load_addr address\n");
32 + exit(1);
33 + }
34 +
35 uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr);
36 uint32_t mb_load_size = 0;
37 mh_entry_addr = ldl_p(header+i+28);
38
39 if (mh_load_end_addr) {
40 + if (mh_bss_end_addr < mh_load_addr) {
41 + fprintf(stderr, "invalid mh_bss_end_addr address\n");
42 + exit(1);
43 + }
44 mb_kernel_size = mh_bss_end_addr - mh_load_addr;
45 +
46 + if (mh_load_end_addr < mh_load_addr) {
47 + fprintf(stderr, "invalid mh_load_end_addr address\n");
48 + exit(1);
49 + }
50 mb_load_size = mh_load_end_addr - mh_load_addr;
51 } else {
52 + if (kernel_file_size < mb_kernel_text_offset) {
53 + fprintf(stderr, "invalid kernel_file_size\n");
54 + exit(1);
55 + }
56 mb_kernel_size = kernel_file_size - mb_kernel_text_offset;
57 mb_load_size = mb_kernel_size;
58 }
59 --
60 2.11.0
61