libdw: Fix overflow in read_encoded_value for the DW_EH_PE_indirect case.
authorMark Wielaard <mjw@redhat.com>
Wed, 27 May 2015 12:05:15 +0000 (14:05 +0200)
committerMark Wielaard <mjw@redhat.com>
Mon, 1 Jun 2015 08:34:11 +0000 (10:34 +0200)
If we are going to dereference a pointer there should be at least enough
data to hold a pointer. Found by afl-fuzz.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
libdw/ChangeLog
libdw/encoded-value.h

index 2757093..aa4d09c 100644 (file)
@@ -1,3 +1,8 @@
+2015-05-27  Mark Wielaard  <mjw@redhat.com>
+
+       * encoded-value.h (read_encoded_value): Check data d_size contains
+       at least enough data to hold a pointer for DW_EH_PE_indirect.
+
 2015-05-22  Mark Wielaard  <mjw@redhat.com>
 
        * dwarf_getsrclines.c (read_srclines): Limit stack usage of lines
index 0fa2018..48d868f 100644 (file)
@@ -214,9 +214,10 @@ read_encoded_value (const Dwarf_CFI *cache, uint8_t encoding,
       if (unlikely (*result < cache->frame_vaddr))
        return true;
       *result -= cache->frame_vaddr;
-      if (unlikely (*result > (cache->data->d.d_size
-                              - encoded_value_size (NULL, cache->e_ident,
-                                                    DW_EH_PE_absptr, NULL))))
+      size_t ptrsize = encoded_value_size (NULL, cache->e_ident,
+                                          DW_EH_PE_absptr, NULL);
+      if (unlikely (cache->data->d.d_size < ptrsize
+                   || *result > (cache->data->d.d_size - ptrsize)))
        return true;
       const uint8_t *ptr = cache->data->d.d_buf + *result;
       if (unlikely (__libdw_cfi_read_address_inc (cache, &ptr, 0, result)