Hi Sayed,

On Wed, 2026-06-17 at 14:41 +0200, Mark Wielaard wrote:
> On Wed, 2026-06-17 at 16:01 +0530, Sayed Kaif wrote:
> > libdw: A crafted .debug_macro section with opcode 0 makes (opcode - 1)
> > wrap to 0xFFFFFFFF in the unsigned array index, writing a 16-byte struct
> > past the 255-element op_protos array. Reject opcode == 0 and add the
> > missing readp >= endp checks before reading the count and opcode bytes.
> > 
> > libdwfl: When rebuilding an ELF from process memory, segments_end used
> > the last PT_LOAD segment's end rather than the largest, so a later
> > smaller segment could shrink contents_size below an earlier segment's
> > start, underflowing end - start into a huge length and overflowing the
> > heap buffer. Skip any segment that starts past contents_size, matching
> > the guard already used in dwfl_segment_report_module.
> 
> Nice finds. Would you mind if I split this patch in two for the two
> separate issues?
> 
> So the first would be covered by:
> 
> >     * libdw/dwarf_getmacros.c (get_macinfo_table): Reject opcode 0,
> >     add bounds checks.
> >     * tests/testfile-macros-opcode0.bz2: New test input.
> >     * tests/run-dwarf-getmacros.sh: Test it.
> >     * tests/Makefile.am (EXTRA_DIST): Add new test file.
> 
> And the second just by:
> 
> >     * libdwfl/elf-from-memory.c (elf_from_remote_memory): Skip
> >     out-of-range segment.

So I pushed the second, but not the first yet.

> > diff --git a/tests/run-dwarf-getmacros.sh b/tests/run-dwarf-getmacros.sh
> > index 220c2426..bda6690d 100755
> > --- a/tests/run-dwarf-getmacros.sh
> > +++ b/tests/run-dwarf-getmacros.sh
> > @@ -707,6 +707,14 @@ file /home/petr/proj/elfutils/master/elfutils/x.c
> >  /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
> > diff --git a/tests/testfile-macros-opcode0.bz2 
> > b/tests/testfile-macros-opcode0.bz2
> > new file mode 100644
> > index 
> > 0000000000000000000000000000000000000000..5e4cb8684065c20b00b0cbde317cf733c8e7a0e9
> > GIT binary patch
> > literal 166
> > zcmZ>Y%CIzaj8qGbRLPmZ%D_<ie?|Sf2OSKK0?ffI4hs7p&u3V`z|f$;FiBuR1_KD(
> > zY8IL`tE$<ds^@~T0|QgBe`;^e{*tG&%sXesEOc`gVcW4$Erf$<3&&MnAtp(|yESS1
> > zV|4@gn65uudF+WtQ?()Ei?+$xjRq_ixOEN1A~kF{KYmWwJ<+}JN!^c@8BCTlt$QYQ
> > S&xl#X`Cq)q)goX5$Xx(&Fh3Ol
> > 
> > literal 0
> > HcmV?d00001

So this testcase doesn't actually trigger the invalid DWARF part.
That is because the test file has single CU DIE with:

DWARF section [ 1] '.debug_info' at offset 0x40:
 [Offset]
 Compilation unit at offset 0:
 Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
 [     b]  compile_unit         abbrev: 1
eu-readelf: DIE [b] cannot get attribute 'GNU_locviews' (sec_offset) value: 
.debug_loc section missing

DWARF section [ 2] '.debug_abbrev' at offset 0x50:
 [ Code]

Abbreviation section at offset 0:
 [    1] offset: 0, children: no, tag: compile_unit
          attr: GNU_locviews, form: sec_offset, offset: 0

DWARF section [ 3] '.debug_macro' at offset 0x59:

 Offset:             0x0
 Version:            4
 Flag:               0x4 (operands_table)
 Offset length:      4
  extension opcode table, 1 items:
    [0]eu-readelf: invalid data

So that is a DW_AT_GNU_locviews and not a DW_AT_GNU_macros.

And the testcase (dwarf_getmacros) tries to follow the DW_AT_GNU_macros
to get at the correct offset in the .debug_macros.

So maybe you attached the wrong testfile?

Thanks,

Mark

Reply via email to