summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2014-12-11 16:28:57 +0100
committerMark Wielaard <mjw@redhat.com>2014-12-15 10:03:03 +0100
commit7d63628b8a72dbeefe8976939c7090f3d1a23311 (patch)
tree6c5e63653d6792a361f37a2534f26a5fb895629a
parentf3111d50756f84e99fbdb6ddfa37d1cd7163fd10 (diff)
downloadelfutils-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/ChangeLog6
-rw-r--r--libelf/elf_begin.c15
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;
}