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 <[email protected]> --- 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 <[email protected]> + + * elf_begin.c (__libelf_next_arhdr_wrlock): ar_size cannot be + negative. Include start_offset in maxsize. + 2014-12-18 Ulrich Drepper <[email protected]> * 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
