* [PATCH] libelf: elf_getphdrnum sanity check the returned phnum result.
@ 2014-11-22 22:15 Mark Wielaard
0 siblings, 0 replies; only message in thread
From: Mark Wielaard @ 2014-11-22 22:15 UTC (permalink / raw)
To: elfutils-devel
[-- Attachment #1: Type: text/plain, Size: 2090 bytes --]
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>
---
libelf/ChangeLog | 5 +++++
libelf/elf_getphdrnum.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 38 insertions(+)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index c7e8d30..b21714e 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -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.
diff --git a/libelf/elf_getphdrnum.c b/libelf/elf_getphdrnum.c
index d8e34d7..50b2fdf 100644
--- a/libelf/elf_getphdrnum.c
+++ b/libelf/elf_getphdrnum.c
@@ -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 (off == 0)
+ {
+ *dst = 0;
+ goto out;
+ }
+
+ if (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 (*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 (elf->maximum_size - off < *dst * phdr_size)
+ *dst = (elf->maximum_size - off) / phdr_size;
+
+out:
rwlock_unlock (elf->lock);
return result;
--
1.9.3
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2014-11-22 22:15 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-22 22:15 [PATCH] libelf: elf_getphdrnum sanity check the returned phnum result Mark Wielaard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).