summaryrefslogtreecommitdiffstats
path: root/libdw
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2018-06-06 23:51:12 +0200
committerMark Wielaard <mark@klomp.org>2018-06-08 12:03:14 +0200
commit64024753424afcd263f5022446be15a920161bd0 (patch)
tree85ea3216cb6791fc401e5bd3fe6a3c397abe8454 /libdw
parent07d2098890e9113079bae64f6fc7f4069f7b12cd (diff)
libdw: Report error in dwarf_getlocation_die for bogus opcode offset.
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>
Diffstat (limited to 'libdw')
-rw-r--r--libdw/ChangeLog5
-rw-r--r--libdw/dwarf_getlocation_die.c8
2 files changed, 13 insertions, 0 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 21adeb7c..b000492e 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -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
diff --git a/libdw/dwarf_getlocation_die.c b/libdw/dwarf_getlocation_die.c
index 00369a9c..673c61cf 100644
--- a/libdw/dwarf_getlocation_die.c
+++ b/libdw/dwarf_getlocation_die.c
@@ -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;