X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=libelf%2Felf_getphdrnum.c;h=061183bb9ac69a2161c3f65bd07675e699c3b572;hb=82c3b58b54026d061a4d81ad95f3023d5d883ab2;hp=99649beef777babb746194899e0bb1e6d4b72397;hpb=a286dd013ef8d46edf013efc0908822a59d8ac81;p=platform%2Fupstream%2Felfutils.git diff --git a/libelf/elf_getphdrnum.c b/libelf/elf_getphdrnum.c index 99649be..061183b 100644 --- a/libelf/elf_getphdrnum.c +++ b/libelf/elf_getphdrnum.c @@ -1,5 +1,5 @@ /* Return number of program headers in the ELF file. - Copyright (C) 2010 Red Hat, Inc. + Copyright (C) 2010, 2014, 2015 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -38,9 +38,8 @@ int -__elf_getphdrnum_rdlock (elf, dst) - Elf *elf; - size_t *dst; +internal_function +__elf_getphdrnum_rdlock (Elf *elf, size_t *dst) { if (unlikely (elf->state.elf64.ehdr == NULL)) { @@ -62,19 +61,63 @@ __elf_getphdrnum_rdlock (elf, dst) /* If there are no section headers, perhaps this is really just 65536 written without PN_XNUM support. Either that or it's bad data. */ - if (likely (scns->cnt > 0)) - *dst = (elf->class == ELFCLASS32 - ? scns->data[0].shdr.e32->sh_info - : scns->data[0].shdr.e64->sh_info); + if (elf->class == ELFCLASS32) + { + if (likely (scns->cnt > 0 + && elf->state.elf32.scns.data[0].shdr.e32 != NULL)) + *dst = scns->data[0].shdr.e32->sh_info; + } + else + { + if (likely (scns->cnt > 0 + && elf->state.elf64.scns.data[0].shdr.e64 != NULL)) + *dst = scns->data[0].shdr.e64->sh_info; + } } return 0; } int -elf_getphdrnum (elf, dst) - Elf *elf; - size_t *dst; +internal_function +__elf_getphdrnum_chk_rdlock (Elf *elf, size_t *dst) +{ + int result = __elf_getphdrnum_rdlock (elf, dst); + + /* Do some sanity checking to make sure phnum and phoff are consistent. */ + Elf64_Off off = (elf->class == ELFCLASS32 + ? elf->state.elf32.ehdr->e_phoff + : elf->state.elf64.ehdr->e_phoff); + if (unlikely (off == 0)) + { + *dst = 0; + return result; + } + + if (unlikely (off >= elf->maximum_size)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + return -1; + } + + /* Check for too many sections. */ + size_t phdr_size = (elf->class == ELFCLASS32 + ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr)); + if (unlikely (*dst > SIZE_MAX / phdr_size)) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + return -1; + } + + /* Truncated file? Don't return more than can be indexed. */ + if (unlikely (elf->maximum_size - off < *dst * phdr_size)) + *dst = (elf->maximum_size - off) / phdr_size; + + return result; +} + +int +elf_getphdrnum (Elf *elf, size_t *dst) { int result; @@ -88,7 +131,7 @@ elf_getphdrnum (elf, dst) } rwlock_rdlock (elf->lock); - result = __elf_getphdrnum_rdlock (elf, dst); + result = __elf_getphdrnum_chk_rdlock (elf, dst); rwlock_unlock (elf->lock); return result;