mirror of
https://github.com/openharmony/third_party_elfutils.git
synced 2026-07-18 09:17:34 -04:00
libelf: elf_getphdrnum sanity check the returned phnum result.
The internal __elf_getphdrnum_rdlock might return an inconsistent phnum. Return a sanitized value, or return an error to users that rely on phnum to be consistent. That way iterating over all phdrs using elf_getphdr will return consistent results. Signed-off-by: Mark Wielaard <mjw@redhat.com>
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
2014-11-22 Mark Wielaard <mjw@redhat.com>
|
||||
|
||||
* elf_getphdrnum.c (elf_getphdrnum): Sanity check the
|
||||
__elf_getphdrnum_rdlock result.
|
||||
|
||||
2014-11-18 Mark Wielaard <mjw@redhat.com>
|
||||
|
||||
* version_xlate.h (elf_cvt_Verdef): Check for overflow.
|
||||
|
||||
@@ -97,6 +97,39 @@ elf_getphdrnum (elf, dst)
|
||||
|
||||
rwlock_rdlock (elf->lock);
|
||||
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;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (unlikely (off >= elf->maximum_size))
|
||||
{
|
||||
__libelf_seterrno (ELF_E_INVALID_DATA);
|
||||
result = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
result = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
out:
|
||||
rwlock_unlock (elf->lock);
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user