]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: Report error in dwarf_getlocation_die for bogus opcode offset.
authorMark Wielaard <mark@klomp.org>
Wed, 6 Jun 2018 21:51:12 +0000 (23:51 +0200)
committerMark Wielaard <mark@klomp.org>
Fri, 8 Jun 2018 10:03:14 +0000 (12:03 +0200)
Found by afl fuzzer on varlocs test. varlocs sanity checks that the
given offset in the opcode corresponds to the cuoffset of the returned
DIE. In case the opcode offset was bogus this might fail because we
might wrap around and return a random DIE instead of reporting an error.

Signed-off-by: Mark Wielaard <mark@klomp.org>
libdw/ChangeLog
libdw/dwarf_getlocation_die.c

index 21adeb7c8c21fcf8509393c64cb53d27c68d0aee..b000492e3b1c8a9ba013006ca50205075bd6165f 100644 (file)
@@ -1,3 +1,8 @@
+2018-06-06  Mark Wielaard  <mark@klomp.org>
+
+       * dwarf_getlocation_die.c (dwarf_getlocation_die): Check offset
+       falls inside cu data.
+
 2018-06-05  Mark Wielaard  <mark@klomp.org>
 
        * dwarf_getsrclines.c (read_srclines): Explicitly set diridx to -1
index 00369a9ccf8b0c63216f216a1d2f6d26f6269bfa..673c61cf6cf0be1a703a356b32804405532bea7a 100644 (file)
@@ -59,6 +59,12 @@ dwarf_getlocation_die (Dwarf_Attribute *attr, const Dwarf_Op *op,
     case DW_OP_GNU_const_type:
     case DW_OP_call2:
     case DW_OP_call4:
+      if (op->number > (attr->cu->end - attr->cu->start))
+       {
+       invalid_offset:
+         __libdw_seterrno (DWARF_E_INVALID_OFFSET);
+         return -1;
+       }
       dieoff = attr->cu->start + op->number;
       break;
 
@@ -66,6 +72,8 @@ dwarf_getlocation_die (Dwarf_Attribute *attr, const Dwarf_Op *op,
     case DW_OP_GNU_regval_type:
     case DW_OP_deref_type:
     case DW_OP_GNU_deref_type:
+      if (op->number2 > (attr->cu->end - attr->cu->start))
+       goto invalid_offset;
       dieoff = attr->cu->start + op->number2;
       break;