From: Roland McGrath Date: Wed, 14 Apr 2010 18:24:15 +0000 (-0700) Subject: Handle truncated phdrs without crash. X-Git-Tag: elfutils-0.146~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=957072c18a906a43f0b428997d0c2b0da478213b;p=thirdparty%2Felfutils.git Handle truncated phdrs without crash. --- diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 2ed2761b7..7e6b99297 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,8 @@ +2010-04-14 Roland McGrath + + * elf32_getphdr.c: Check for e_phoff/size outside the file bounds. + * elf_begin.c (file_read_elf): Don't set .phdr here. + 2010-04-13 Roland McGrath * elf.h: Update from glibc. diff --git a/libelf/elf32_getphdr.c b/libelf/elf32_getphdr.c index 0a617a67e..507fc2aa5 100644 --- a/libelf/elf32_getphdr.c +++ b/libelf/elf32_getphdr.c @@ -105,6 +105,13 @@ __elfw2(LIBELFBITS,getphdr_wrlock) (elf) size_t size = phnum * sizeof (ElfW2(LIBELFBITS,Phdr)); + if (ehdr->e_phoff < elf->maximum_size + || elf->maximum_size - ehdr->e_phoff < size) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + goto out; + } + if (elf->map_address != NULL) { /* All the data is already mapped. Use it. */ diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c index 0b9583b26..e46add330 100644 --- a/libelf/elf_begin.c +++ b/libelf/elf_begin.c @@ -326,11 +326,9 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, elf->state.elf32.ehdr = ehdr; elf->state.elf32.shdr = (Elf32_Shdr *) ((char *) ehdr + ehdr->e_shoff); - if (ehdr->e_phnum > 0) - /* Assign a value only if there really is a program - header. Otherwise the value remains NULL. */ - elf->state.elf32.phdr - = (Elf32_Phdr *) ((char *) ehdr + ehdr->e_phoff); + + /* Don't precache the phdr pointer here. + elf32_getphdr will validate it against the size when asked. */ for (size_t cnt = 0; cnt < scncnt; ++cnt) { @@ -414,11 +412,9 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, elf->state.elf64.ehdr = ehdr; elf->state.elf64.shdr = (Elf64_Shdr *) ((char *) ehdr + ehdr->e_shoff); - if (ehdr->e_phnum > 0) - /* Assign a value only if there really is a program - header. Otherwise the value remains NULL. */ - elf->state.elf64.phdr - = (Elf64_Phdr *) ((char *) ehdr + ehdr->e_phoff); + + /* Don't precache the phdr pointer here. + elf64_getphdr will validate it against the size when asked. */ for (size_t cnt = 0; cnt < scncnt; ++cnt) {