]> git.pld-linux.org Git - packages/xen.git/blob - 0013-libelf-Make-all-callers-call-elf_check_broken.patch
43fe7f06af2f078e8f5e086b673b9d716e8a0e9e
[packages/xen.git] / 0013-libelf-Make-all-callers-call-elf_check_broken.patch
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
5
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.
13
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
16 out".
17
18 Difference in the 4.2 series, compared to unstable:
19
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.
23
24 This is part of the fix to a security issue, XSA-55.
25
26 Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
27
28 xen-unstable version Reviewed-by: George Dunlap <george.dunlap@eu.citrix.com>
29 ---
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(-)
36
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);
43      }
44  
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));
51 +
52      if ( tables == 0 )
53      {
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)
56      {
57          xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: ELF image"
58                       " has no shstrtab", __FUNCTION__);
59 -        return -EINVAL;
60 +        rc = -EINVAL;
61 +        goto out;
62      }
63  
64      /* parse binary and get xen meta info */
65      elf_parse_binary(elf);
66      if ( (rc = elf_xen_parse(elf, &dom->parms)) != 0 )
67 -        return rc;
68 +    {
69 +        goto out;
70 +    }
71  
72      if ( elf_xen_feature_get(XENFEAT_dom0, dom->parms.f_required) )
73      {
74          xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Kernel does not"
75                       " support unprivileged (DomU) operation", __FUNCTION__);
76 -        return -EINVAL;
77 +        rc = -EINVAL;
78 +        goto out;
79      }
80  
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);
86 -    return 0;
87 +    rc = 0;
88 +out:
89 +    if ( elf_check_broken(elf) )
90 +        DOMPRINTF("%s: ELF broken: %s", __FUNCTION__,
91 +                  elf_check_broken(elf));
92 +
93 +    return rc;
94  }
95  
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);
103      }
104  
105 +    if ( elf_check_broken(&elf) )
106 +        ERROR("HVM ELF broken: %s", elf_check_broken(&elf));
107 +
108      free(page_array);
109      return 0;
110  
111   error_out:
112      free(page_array);
113 +    if ( elf_check_broken(&elf) )
114 +        ERROR("HVM ELF broken, failing: %s", elf_check_broken(&elf));
115      return -1;
116  }
117  
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)));
125  
126 +       if (elf_check_broken(&elf))
127 +               printf("warning: broken ELF: %s\n", elf_check_broken(&elf));
128 +
129         return 0;
130  }
131  
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)
137  {
138      int rc;
139  
140 +    memset(&info->elf.elf, 0, sizeof(info->elf.elf));
141 +
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)
146  #endif
147      elf_parse_binary(&info->elf.elf);
148      if ( (rc = elf_xen_parse(&info->elf.elf, &info->elf.parms)) != 0 )
149 -        return rc;
150 +        goto err;
151  
152      /*
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;
157  
158 +    if ( elf_check_broken(&info->elf.elf) )
159 +        printk("Xen: warning: ELF kernel broken: %s\n",
160 +               elf_check_broken(&info->elf.elf));
161 +
162      return 0;
163 +
164 +err:
165 +    if ( elf_check_broken(&info->elf.elf) )
166 +        printk("Xen: ELF kernel broken: %s\n",
167 +               elf_check_broken(&info->elf.elf));
168 +
169 +    return rc;
170  }
171  
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(
178  #endif
179      elf_parse_binary(&elf);
180      if ( (rc = elf_xen_parse(&elf, &parms)) != 0 )
181 -        return rc;
182 +        goto out;
183  
184      /* compatibility check */
185      compatible = 0;
186 @@ -413,14 +413,16 @@ int __init construct_dom0(
187      if ( !compatible )
188      {
189          printk("Mismatch between Xen and DOM0 kernel\n");
190 -        return -EINVAL;
191 +        rc = -EINVAL;
192 +        goto out;
193      }
194  
195      if ( parms.elf_notes[XEN_ELFNOTE_SUPPORTED_FEATURES].type != XEN_ENT_NONE &&
196           !test_bit(XENFEAT_dom0, parms.f_supported) )
197      {
198          printk("Kernel does not support Dom0 operation\n");
199 -        return -EINVAL;
200 +        rc = -EINVAL;
201 +        goto out;
202      }
203  
204  #if defined(__x86_64__)
205 @@ -734,7 +736,8 @@ int __init construct_dom0(
206           (v_end > HYPERVISOR_COMPAT_VIRT_START(d)) )
207      {
208          printk("DOM0 image overlaps with Xen private area.\n");
209 -        return -EINVAL;
210 +        rc = -EINVAL;
211 +        goto out;
212      }
213  
214      if ( is_pv_32on64_domain(d) )
215 @@ -914,7 +917,7 @@ int __init construct_dom0(
216      if ( rc < 0 )
217      {
218          printk("Failed to load the kernel binary\n");
219 -        return rc;
220 +        goto out;
221      }
222      bootstrap_map(NULL);
223  
224 @@ -925,7 +928,8 @@ int __init construct_dom0(
225          {
226              write_ptbase(current);
227              printk("Invalid HYPERCALL_PAGE field in ELF notes.\n");
228 -            return -1;
229 +            rc = -1;
230 +            goto out;
231          }
232          hypercall_page_initialise(
233              d, (void *)(unsigned long)parms.virt_hypercall);
234 @@ -1272,9 +1276,19 @@ int __init construct_dom0(
235  
236      BUG_ON(rc != 0);
237  
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));
242  
243 +    iommu_dom0_init(dom0);
244      return 0;
245 +
246 +out:
247 +    if ( elf_check_broken(&elf) )
248 +        printk(" Xen dom0 kernel broken ELF: %s\n",
249 +               elf_check_broken(&elf));
250 +
251 +    return rc;
252  }
253  
254  /*
255 -- 
256 1.7.2.5
257
This page took 0.035431 seconds and 2 git commands to generate.