if ((flags & 0x4) != 0)
{
+ if (readp >= endp)
+ goto invalid_dwarf;
unsigned count = *readp++;
for (unsigned i = 0; i < count; ++i)
{
+ if (readp >= endp)
+ goto invalid;
unsigned opcode = *readp++;
+ /* Opcode 0 is not allocated (and 0xff means "not stored").
+ Reject it here: without this check the unsigned expression
+ opcode - 1 wraps to UINT_MAX for opcode == 0, and the
+ assignment below would write a Dwarf_Macro_Op_Proto far out
+ of the bounds of the op_protos[255] stack array. */
+ if (opcode == 0)
+ goto invalid;
+
Dwarf_Macro_Op_Proto e;
if (readp >= endp)
goto invalid;
testfile45.S.bz2 testfile45.expect.bz2 run-disasm-x86-64.sh \
testfile46.bz2 testfile47.bz2 testfile48.bz2 testfile48.debug.bz2 \
testfile49.bz2 testfile50.bz2 testfile51.bz2 \
- testfile-macros-0xff.bz2 \
+ testfile-macros-0xff.bz2 testfile-macros-opcode0.bz2 \
run-readelf-macro.sh testfilemacro.bz2 testfileclangmacro.bz2 \
run-readelf-loc.sh testfileloc.bz2 \
splitdwarf4-not-split4.dwo.bz2 \
/file
EOF
+# A .debug_macro opcode_operands_table that defines opcode 0 used to make
+# get_table_for_offset() compute op_protos[(unsigned)0 - 1] and write far
+# out of bounds. It must now be rejected as invalid DWARF.
+testfiles testfile-macros-opcode0
+testrun_compare ${abs_builddir}/dwarf-getmacros testfile-macros-opcode0 0xb <<\EOF
+invalid DWARF
+EOF
+
# See testfile-dwp.source.
testfiles testfile-dwp-5 testfile-dwp-5.dwp
testfiles testfile-dwp-4-strict testfile-dwp-4-strict.dwp