]>
Commit | Line | Data |
---|---|---|
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 |