# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 14717dedba028c7e98bff1f67c6e9e25b42b5661
# Parent 0f16f0871dc950fe85ece7e7a2e154383ae7c345
[LOADER] More sanity checks when parsing Elf images to avoid
out-of-bounds array accesses when loading the image.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
tools/libxc/xc_load_elf.c | 17 ++++++++++++-----
xen/common/elf.c | 17 ++++++++++++-----
2 files changed, 24 insertions(+), 10 deletions(-)
diff -r 0f16f0871dc9 -r 14717dedba02 tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Sun May 21 19:05:31 2006 +0100
+++ b/tools/libxc/xc_load_elf.c Sun May 21 20:15:58 2006 +0100
@@ -158,12 +158,17 @@ static int parseelfimage(const char *ima
elf_pa_off_defined = (p != NULL);
elf_pa_off = elf_pa_off_defined ? strtoul(p+17, &p, 0) : virt_base;
+ if ( elf_pa_off_defined && !virt_base_defined )
+ goto bad_image;
+
for ( h = 0; h < ehdr->e_phnum; h++ )
{
phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize));
if ( !is_loadable_phdr(phdr) )
continue;
vaddr = phdr->p_paddr - elf_pa_off + virt_base;
+ if ( (vaddr + phdr->p_memsz) < vaddr )
+ goto bad_image;
if ( vaddr < kernstart )
kernstart = vaddr;
if ( (vaddr + phdr->p_memsz) > kernend )
@@ -184,11 +189,9 @@ static int parseelfimage(const char *ima
if ( (kernstart > kernend) ||
(dsi->v_kernentry < kernstart) ||
- (dsi->v_kernentry > kernend) )
- {
- ERROR("Malformed ELF image.");
- return -EINVAL;
- }
+ (dsi->v_kernentry > kernend) ||
+ (dsi->v_start > kernstart) )
+ goto bad_image;
if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
dsi->load_symtab = 1;
@@ -200,6 +203,10 @@ static int parseelfimage(const char *ima
loadelfsymtab(image, 0, 0, NULL, dsi);
return 0;
+
+ bad_image:
+ ERROR("Malformed ELF image.");
+ return -EINVAL;
}
static int
diff -r 0f16f0871dc9 -r 14717dedba02 xen/common/elf.c
--- a/xen/common/elf.c Sun May 21 19:05:31 2006 +0100
+++ b/xen/common/elf.c Sun May 21 20:15:58 2006 +0100
@@ -94,12 +94,17 @@ int parseelfimage(struct domain_setup_in
elf_pa_off_defined = (p != NULL);
elf_pa_off = elf_pa_off_defined ? simple_strtoul(p+17, &p, 0) : virt_base;
+ if ( elf_pa_off_defined && !virt_base_defined )
+ goto bad_image;
+
for ( h = 0; h < ehdr->e_phnum; h++ )
{
phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
if ( !is_loadable_phdr(phdr) )
continue;
vaddr = phdr->p_paddr - elf_pa_off + virt_base;
+ if ( (vaddr + phdr->p_memsz) < vaddr )
+ goto bad_image;
if ( vaddr < kernstart )
kernstart = vaddr;
if ( (vaddr + phdr->p_memsz) > kernend )
@@ -120,11 +125,9 @@ int parseelfimage(struct domain_setup_in
if ( (kernstart > kernend) ||
(dsi->v_kernentry < kernstart) ||
- (dsi->v_kernentry > kernend) )
- {
- printk("Malformed ELF image.\n");
- return -EINVAL;
- }
+ (dsi->v_kernentry > kernend) ||
+ (dsi->v_start > kernstart) )
+ goto bad_image;
if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
dsi->load_symtab = 1;
@@ -136,6 +139,10 @@ int parseelfimage(struct domain_setup_in
loadelfsymtab(dsi, 0);
return 0;
+
+ bad_image:
+ printk("Malformed ELF image.\n");
+ return -EINVAL;
}
int loadelfimage(struct domain_setup_info *dsi)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|