Don't trust the ar header offset and size. When creating an Elf
descriptor for an ar member check the offset isn't past the end of the
containing Elf and don't use/set the member maximum_size larger than
the remaining size of the parent.
* libelf/elf_begin.c (dup_elf): Only call read_file if the
offset isn't past the end and with a maximum_size not too large.
Signed-off-by: Mark Wielaard <[email protected]>
---
This, plus Aaron's fix for libdw_open_elf, should resolve the ossfuzz
issues.
libelf/elf_begin.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 7e722ea642b9..d3ab887d34e3 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -1113,9 +1113,16 @@ dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
return NULL;
/* We have all the information we need about the next archive member.
- Now create a descriptor for it. */
- result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
- ref->state.ar.elf_ar_hdr.ar_size, cmd, ref);
+ Now create a descriptor for it. Check parent size can contain member. */
+ size_t max_size = ref->maximum_size;
+ size_t offset = (size_t) ref->state.ar.offset;
+ size_t hdr_size = sizeof (struct ar_hdr);
+ size_t ar_size = (size_t) ref->state.ar.elf_ar_hdr.ar_size;
+ if (max_size - hdr_size < offset)
+ return NULL;
+ else
+ result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
+ MIN (max_size - hdr_size - offset, ar_size), cmd, ref);
if (result != NULL)
{
--
2.50.1