1 From a965b8f80388603d439ae2b8ee7b9b018a079f90 Mon Sep 17 00:00:00 2001
2 From: Ian Jackson <ian.jackson@eu.citrix.com>
3 Date: Fri, 14 Jun 2013 16:43:17 +0100
4 Subject: [PATCH 13/23] libelf: Make all callers call elf_check_broken
6 This arranges that if the new pointer reference error checking
7 tripped, we actually get a message about it. In this patch these
8 messages do not change the actual return values from the various
9 functions: so pointer reference errors do not prevent loading. This
10 is for fear that some existing kernels might cause the code to make
11 these wild references, which would then break, which is not a good
12 thing in a security patch.
14 In xen/arch/x86/domain_build.c we have to introduce an "out" label and
15 change all of the "return rc" beyond the relevant point into "goto
18 Difference in the 4.2 series, compared to unstable:
20 * tools/libxc/xc_hvm_build_x86.c:setup_guest and
21 xen/arch/arm/kernel.c:kernel_try_elf_prepare have different
22 error handling in 4.2 to unstable; patch adjusted accordingly.
24 This is part of the fix to a security issue, XSA-55.
26 Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
28 xen-unstable version Reviewed-by: George Dunlap <george.dunlap@eu.citrix.com>
30 tools/libxc/xc_dom_elfloader.c | 25 +++++++++++++++++++++----
31 tools/libxc/xc_hvm_build_x86.c | 5 +++++
32 tools/xcutils/readnotes.c | 3 +++
33 xen/arch/arm/kernel.c | 15 ++++++++++++++-
34 xen/arch/x86/domain_build.c | 28 +++++++++++++++++++++-------
35 5 files changed, 64 insertions(+), 12 deletions(-)
37 diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
38 index ea45886..4fb4da2 100644
39 --- a/tools/libxc/xc_dom_elfloader.c
40 +++ b/tools/libxc/xc_dom_elfloader.c
41 @@ -276,6 +276,13 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
42 elf_store_field(elf, shdr, e32.sh_name, 0);
45 + if ( elf_check_broken(&syms) )
46 + DOMPRINTF("%s: symbols ELF broken: %s", __FUNCTION__,
47 + elf_check_broken(&syms));
48 + if ( elf_check_broken(elf) )
49 + DOMPRINTF("%s: ELF broken: %s", __FUNCTION__,
50 + elf_check_broken(elf));
54 DOMPRINTF("%s: no symbol table present", __FUNCTION__);
55 @@ -312,19 +319,23 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
57 xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: ELF image"
58 " has no shstrtab", __FUNCTION__);
64 /* parse binary and get xen meta info */
65 elf_parse_binary(elf);
66 if ( (rc = elf_xen_parse(elf, &dom->parms)) != 0 )
72 if ( elf_xen_feature_get(XENFEAT_dom0, dom->parms.f_required) )
74 xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Kernel does not"
75 " support unprivileged (DomU) operation", __FUNCTION__);
81 /* find kernel segment */
82 @@ -338,7 +349,13 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
83 DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "",
84 __FUNCTION__, dom->guest_type,
85 dom->kernel_seg.vstart, dom->kernel_seg.vend);
89 + if ( elf_check_broken(elf) )
90 + DOMPRINTF("%s: ELF broken: %s", __FUNCTION__,
91 + elf_check_broken(elf));
96 static int xc_dom_load_elf_kernel(struct xc_dom_image *dom)
97 diff --git a/tools/libxc/xc_hvm_build_x86.c b/tools/libxc/xc_hvm_build_x86.c
98 index ccfd8b5..8165287 100644
99 --- a/tools/libxc/xc_hvm_build_x86.c
100 +++ b/tools/libxc/xc_hvm_build_x86.c
101 @@ -403,11 +403,16 @@ static int setup_guest(xc_interface *xch,
102 munmap(page0, PAGE_SIZE);
105 + if ( elf_check_broken(&elf) )
106 + ERROR("HVM ELF broken: %s", elf_check_broken(&elf));
113 + if ( elf_check_broken(&elf) )
114 + ERROR("HVM ELF broken, failing: %s", elf_check_broken(&elf));
118 diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
119 index cfae994..d1f7a30 100644
120 --- a/tools/xcutils/readnotes.c
121 +++ b/tools/xcutils/readnotes.c
122 @@ -301,6 +301,9 @@ int main(int argc, char **argv)
123 printf("__xen_guest: %s\n",
124 elf_strfmt(&elf, elf_section_start(&elf, shdr)));
126 + if (elf_check_broken(&elf))
127 + printf("warning: broken ELF: %s\n", elf_check_broken(&elf));
132 diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c
133 index 2d56130..dec0519 100644
134 --- a/xen/arch/arm/kernel.c
135 +++ b/xen/arch/arm/kernel.c
136 @@ -146,6 +146,8 @@ static int kernel_try_elf_prepare(struct kernel_info *info)
140 + memset(&info->elf.elf, 0, sizeof(info->elf.elf));
142 info->kernel_order = get_order_from_bytes(KERNEL_FLASH_SIZE);
143 info->kernel_img = alloc_xenheap_pages(info->kernel_order, 0);
144 if ( info->kernel_img == NULL )
145 @@ -160,7 +162,7 @@ static int kernel_try_elf_prepare(struct kernel_info *info)
147 elf_parse_binary(&info->elf.elf);
148 if ( (rc = elf_xen_parse(&info->elf.elf, &info->elf.parms)) != 0 )
153 * TODO: can the ELF header be used to find the physical address
154 @@ -169,7 +171,18 @@ static int kernel_try_elf_prepare(struct kernel_info *info)
155 info->entry = info->elf.parms.virt_entry;
156 info->load = kernel_elf_load;
158 + if ( elf_check_broken(&info->elf.elf) )
159 + printk("Xen: warning: ELF kernel broken: %s\n",
160 + elf_check_broken(&info->elf.elf));
165 + if ( elf_check_broken(&info->elf.elf) )
166 + printk("Xen: ELF kernel broken: %s\n",
167 + elf_check_broken(&info->elf.elf));
172 int kernel_prepare(struct kernel_info *info)
173 diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
174 index a655b21..0dbec96 100644
175 --- a/xen/arch/x86/domain_build.c
176 +++ b/xen/arch/x86/domain_build.c
177 @@ -374,7 +374,7 @@ int __init construct_dom0(
179 elf_parse_binary(&elf);
180 if ( (rc = elf_xen_parse(&elf, &parms)) != 0 )
184 /* compatibility check */
186 @@ -413,14 +413,16 @@ int __init construct_dom0(
189 printk("Mismatch between Xen and DOM0 kernel\n");
195 if ( parms.elf_notes[XEN_ELFNOTE_SUPPORTED_FEATURES].type != XEN_ENT_NONE &&
196 !test_bit(XENFEAT_dom0, parms.f_supported) )
198 printk("Kernel does not support Dom0 operation\n");
204 #if defined(__x86_64__)
205 @@ -734,7 +736,8 @@ int __init construct_dom0(
206 (v_end > HYPERVISOR_COMPAT_VIRT_START(d)) )
208 printk("DOM0 image overlaps with Xen private area.\n");
214 if ( is_pv_32on64_domain(d) )
215 @@ -914,7 +917,7 @@ int __init construct_dom0(
218 printk("Failed to load the kernel binary\n");
224 @@ -925,7 +928,8 @@ int __init construct_dom0(
226 write_ptbase(current);
227 printk("Invalid HYPERCALL_PAGE field in ELF notes.\n");
232 hypercall_page_initialise(
233 d, (void *)(unsigned long)parms.virt_hypercall);
234 @@ -1272,9 +1276,19 @@ int __init construct_dom0(
238 - iommu_dom0_init(dom0);
239 + if ( elf_check_broken(&elf) )
240 + printk(" Xen warning: dom0 kernel broken ELF: %s\n",
241 + elf_check_broken(&elf));
243 + iommu_dom0_init(dom0);
247 + if ( elf_check_broken(&elf) )
248 + printk(" Xen dom0 kernel broken ELF: %s\n",
249 + elf_check_broken(&elf));