summaryrefslogtreecommitdiffstats
path: root/libelf
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2015-01-20 14:52:41 +0100
committerMark Wielaard <[email protected]>2015-02-06 22:18:52 +0100
commit058ae7b4d5bdfa0f39312b056ee9cadc4c3ffeb9 (patch)
treebb41cd47b381b0d698ff2e5ef96dfbce635e02a4 /libelf
parentc806736dc8ba24bf126d3942aaa755e7d4f86ea9 (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/ChangeLog5
-rw-r--r--libelf/elf_strptr.c12
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);