diff options
author | Mark Wielaard <mjw@redhat.com> | 2014-12-11 16:28:57 +0100 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2014-12-15 10:03:03 +0100 |
commit | 7d63628b8a72dbeefe8976939c7090f3d1a23311 (patch) | |
tree | 6c5e63653d6792a361f37a2534f26a5fb895629a | |
parent | f3111d50756f84e99fbdb6ddfa37d1cd7163fd10 (diff) | |
download | elfutils-7d63628b8a72dbeefe8976939c7090f3d1a23311.tar.gz |
libelf: Add some ar header sanity checking.
Don't allow entries or size to overflow the parent file size.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
-rw-r--r-- | libelf/ChangeLog | 6 | ||||
-rw-r--r-- | libelf/elf_begin.c | 15 |
2 files changed, 18 insertions, 3 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 4860530b..e4c58499 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,9 @@ +2014-12-11 Mark Wielaard <mjw@redhat.com> + + * elf_begin.c (read_long_names): Check for offset overflow. + (__libelf_next_arhdr_wrlock): Likewise. Sanity check the ar_size. + Don't allow it to go beyond end of file. + 2014-12-09 Mark Wielaard <mjw@redhat.com> * elf_getarsym.c (elf_getarsym): Make sure n * w doesn't overflow. diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c index d135deab..99a9c0a0 100644 --- a/libelf/elf_begin.c +++ b/libelf/elf_begin.c @@ -673,7 +673,8 @@ read_long_names (Elf *elf) { if (elf->map_address != NULL) { - if (offset + sizeof (struct ar_hdr) > elf->maximum_size) + if ((size_t) offset > elf->maximum_size + || elf->maximum_size - offset < sizeof (struct ar_hdr)) return NULL; /* The data is mapped. */ @@ -767,8 +768,10 @@ __libelf_next_arhdr_wrlock (elf) if (elf->map_address != NULL) { /* See whether this entry is in the file. */ - if (unlikely (elf->state.ar.offset + sizeof (struct ar_hdr) - > elf->start_offset + elf->maximum_size)) + if (unlikely ((size_t) elf->state.ar.offset + > elf->start_offset + elf->maximum_size + || (elf->start_offset + elf->maximum_size + - elf->state.ar.offset) < sizeof (struct ar_hdr))) { /* This record is not anymore in the file. */ __libelf_seterrno (ELF_E_RANGE); @@ -912,6 +915,12 @@ __libelf_next_arhdr_wrlock (elf) INT_FIELD (ar_mode); INT_FIELD (ar_size); + /* Truncated file? */ + size_t maxsize; + maxsize = 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; + return 0; } |