summaryrefslogtreecommitdiffstats
path: root/libelf/elf32_getphdr.c
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2014-11-17 00:33:36 +0100
committerMark Wielaard <mjw@redhat.com>2014-11-17 00:33:36 +0100
commit436275edd015ab6a6f8e164ee2292f74f03d2413 (patch)
tree3ae7d3d504f409719f7e3194b5121cfc1ccc8c32 /libelf/elf32_getphdr.c
parent2af7b4942ad1e08d6e0609afec4edc82588f089e (diff)
downloadandroid_external_elfutils-436275edd015ab6a6f8e164ee2292f74f03d2413.tar.gz
android_external_elfutils-436275edd015ab6a6f8e164ee2292f74f03d2413.tar.bz2
android_external_elfutils-436275edd015ab6a6f8e164ee2292f74f03d2413.zip
libelf: Fix handling of (extended) phnum.
If there is no e_phoff e_phnum cannot be trusted. Extended phnum can only be gotten if we have an actual section table and a shdr for section zero, Extended phnum can be too large to fit in the file (or a size_t). Signed-off-by: Mark Wielaard <mjw@redhat.com>
Diffstat (limited to 'libelf/elf32_getphdr.c')
-rw-r--r--libelf/elf32_getphdr.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/libelf/elf32_getphdr.c b/libelf/elf32_getphdr.c
index e74e63fd..1b82a480 100644
--- a/libelf/elf32_getphdr.c
+++ b/libelf/elf32_getphdr.c
@@ -76,15 +76,17 @@ __elfw2(LIBELFBITS,getphdr_wrlock) (elf)
size_t phnum;
if (__elf_getphdrnum_rdlock (elf, &phnum) != 0)
goto out;
- if (phnum == 0)
+ if (phnum == 0 || ehdr->e_phoff == 0)
{
__libelf_seterrno (ELF_E_NO_PHDR);
goto out;
}
+ /* Check this doesn't overflow. */
size_t size = phnum * sizeof (ElfW2(LIBELFBITS,Phdr));
- if (ehdr->e_phoff > elf->maximum_size
+ if (phnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))
+ || ehdr->e_phoff > elf->maximum_size
|| elf->maximum_size - ehdr->e_phoff < size)
{
__libelf_seterrno (ELF_E_INVALID_DATA);