Elf_Arhdr ar_size is loff_t, which is signed. Make sure it isn't negative.
When the parent start_offset is non-zero maxsize should include it to
compensate for ar offset.
Found with afl-fuzz.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libelf/ChangeLog | 5 +++++
libelf/elf_begin.c | 9 ++++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 3b88d03..6a1c925 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2014-12-25 Mark Wielaard <mjw(a)redhat.com>
+
+ * elf_begin.c (__libelf_next_arhdr_wrlock): ar_size cannot be
+ negative. Include start_offset in maxsize.
+
2014-12-18 Ulrich Drepper <drepper(a)gmail.com>
* Makefile.am: Suppress output of textrel_check command.
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 30abe0b..947b0ed 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -924,9 +924,16 @@ __libelf_next_arhdr_wrlock (elf)
INT_FIELD (ar_mode);
INT_FIELD (ar_size);
+ if (elf_ar_hdr->ar_size < 0)
+ {
+ __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
+ return -1;
+ }
+
/* Truncated file? */
size_t maxsize;
- maxsize = elf->maximum_size - elf->state.ar.offset - sizeof (struct ar_hdr);
+ maxsize = (elf->start_offset + elf->maximum_size
+ - elf->state.ar.offset - sizeof (struct ar_hdr));
if ((size_t) elf_ar_hdr->ar_size > maxsize)
elf_ar_hdr->ar_size = maxsize;
--
1.8.3.1
Show replies by date