diff options
| author | Mark Wielaard <[email protected]> | 2015-01-20 14:52:41 +0100 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2015-02-06 22:18:52 +0100 |
| commit | 058ae7b4d5bdfa0f39312b056ee9cadc4c3ffeb9 (patch) | |
| tree | bb41cd47b381b0d698ff2e5ef96dfbce635e02a4 /libelf | |
| parent | c806736dc8ba24bf126d3942aaa755e7d4f86ea9 (diff) | |
libelf: elf_strptr should fetch the shdr for the section if not yet known.
elf_strptr might be called before the shdrs are read in. In that case it
needs to explicitly call __elf[32|64]_getshdr_rdlock to check the section
type and size. The new strptr testcase triggers this corner case and crashes
before the fix.
Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'libelf')
| -rw-r--r-- | libelf/ChangeLog | 5 | ||||
| -rw-r--r-- | libelf/elf_strptr.c | 12 |
2 files changed, 12 insertions, 5 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 2ca95092..0ee94d4e 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,8 @@ +2015-01-20 Mark Wielaard <[email protected]> + + * elf_strptr.c (elf_strptr): Call __elf[32|64]_getshdr_rdlock if + necessary. + 2014-12-30 Mark Wielaard <[email protected]> * elf_getphdrnum.c (__elf_getphdrnum_chk_rdlock): New function. diff --git a/libelf/elf_strptr.c b/libelf/elf_strptr.c index 1f404292..f30a06fc 100644 --- a/libelf/elf_strptr.c +++ b/libelf/elf_strptr.c @@ -1,5 +1,5 @@ /* Return string pointer from string section. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2008, 2009 Red Hat, Inc. + Copyright (C) 1998-2002, 2004, 2008, 2009, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <[email protected]>, 1998. @@ -88,14 +88,15 @@ elf_strptr (elf, idx, offset) if (elf->class == ELFCLASS32) { - if (unlikely (strscn->shdr.e32->sh_type != SHT_STRTAB)) + Elf32_Shdr *shdr = strscn->shdr.e32 ?: __elf32_getshdr_rdlock (strscn); + if (unlikely (shdr->sh_type != SHT_STRTAB)) { /* This is no string section. */ __libelf_seterrno (ELF_E_INVALID_SECTION); goto out; } - if (unlikely (offset >= strscn->shdr.e32->sh_size)) + if (unlikely (offset >= shdr->sh_size)) { /* The given offset is too big, it is beyond this section. */ __libelf_seterrno (ELF_E_OFFSET_RANGE); @@ -104,14 +105,15 @@ elf_strptr (elf, idx, offset) } else { - if (unlikely (strscn->shdr.e64->sh_type != SHT_STRTAB)) + Elf64_Shdr *shdr = strscn->shdr.e64 ?: __elf64_getshdr_rdlock (strscn); + if (unlikely (shdr->sh_type != SHT_STRTAB)) { /* This is no string section. */ __libelf_seterrno (ELF_E_INVALID_SECTION); goto out; } - if (unlikely (offset >= strscn->shdr.e64->sh_size)) + if (unlikely (offset >= shdr->sh_size)) { /* The given offset is too big, it is beyond this section. */ __libelf_seterrno (ELF_E_OFFSET_RANGE); |
