diff options
| author | Omar Sandoval <[email protected]> | 2020-03-18 13:18:51 -0700 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2020-03-23 11:23:24 +0100 |
| commit | ee2dd07f57a43e1802461a65248438257ea94e58 (patch) | |
| tree | 5d15d9be5853f53dd29ffea8dd896de903aff39c /libelf/elf_getphdrnum.c | |
| parent | 5d67e9d3eaa6442b781cd6d8ce38a53b17136d12 (diff) | |
libelf: handle PN_XNUM in elf_getphdrnum before shdr 0 is cached
__elf_getphdrnum_rdlock() handles PN_XNUM by getting sh_info from
elf->state.elf{32,64}.scns.data[0].shdr.e{32,64}. However, that is only
a cache that may or may not have been populated by elf_begin() or
elf{32,64}_getshdr(); if it hasn't been cached yet, elf_getphdrnum()
returns 65535 (the value of PN_XNUM) instead. We should explicitly get
the shdr if it isn't cached.
Signed-off-by: Omar Sandoval <[email protected]>
Diffstat (limited to 'libelf/elf_getphdrnum.c')
| -rw-r--r-- | libelf/elf_getphdrnum.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/libelf/elf_getphdrnum.c b/libelf/elf_getphdrnum.c index f91cba98..53617dfc 100644 --- a/libelf/elf_getphdrnum.c +++ b/libelf/elf_getphdrnum.c @@ -63,15 +63,23 @@ __elf_getphdrnum_rdlock (Elf *elf, size_t *dst) 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; + if (likely (scns->cnt > 0)) + { + Elf_Scn *scn = &elf->state.elf32.scns.data[0]; + Elf32_Shdr *shdr = scn->shdr.e32 ?: __elf32_getshdr_rdlock (scn); + if (shdr) + *dst = shdr->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; + if (likely (scns->cnt > 0)) + { + Elf_Scn *scn = &elf->state.elf64.scns.data[0]; + Elf64_Shdr *shdr = scn->shdr.e64 ?: __elf64_getshdr_rdlock (scn); + if (shdr) + *dst = shdr->sh_info; + } } } |
