For DW_LNS_const_add_pc and special opcodes don't accept line_range being zero. Signed-off-by: Mark Wielaard --- libdw/ChangeLog | 5 +++++ libdw/dwarf_getsrclines.c | 6 ++++++ src/ChangeLog | 5 +++++ src/readelf.c | 7 +++++++ 4 files changed, 23 insertions(+) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 2241c70..3e77994 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,8 @@ +2014-11-24 Mark Wielaard + + * dwarf_getsrclines.c (read_srclines): Check line_range is not zero + before usage. + 2014-11-23 Mark Wielaard * dwarf_attr.c (dwarf_attr): Check __libdw_find_attr return value. diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c index 15881e8..efdc00f 100644 --- a/libdw/dwarf_getsrclines.c +++ b/libdw/dwarf_getsrclines.c @@ -365,6 +365,9 @@ read_srclines (Dwarf *dbg, /* Is this a special opcode? */ if (likely (opcode >= opcode_base)) { + if (line_range == 0) + goto invalid_data; + /* Yes. Handling this is quite easy since the opcode value is computed with @@ -576,6 +579,9 @@ read_srclines (Dwarf *dbg, if (unlikely (standard_opcode_lengths[opcode] != 0)) goto invalid_data; + if (line_range == 0) + goto invalid_data; + advance_pc ((255 - opcode_base) / line_range); break; diff --git a/src/ChangeLog b/src/ChangeLog index 19509dc..0082e65 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2014-11-24 Mark Wielaard + + * readelf.c (print_debug_line_section): Check line_range is not zero + before usage. + 2014-11-23 Mark Wielaard * readelf.c (print_debug_aranges_section): Check length to catch diff --git a/src/readelf.c b/src/readelf.c index ffc14fd..7573898 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -6507,6 +6507,9 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, /* Is this a special opcode? */ if (likely (opcode >= opcode_base)) { + if (line_range == 0) + goto invalid_unit; + /* Yes. Handling this is quite easy since the opcode value is computed with @@ -6682,6 +6685,10 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, case DW_LNS_const_add_pc: /* Takes no argument. */ + + if (line_range == 0) + goto invalid_unit; + advance_pc ((255 - opcode_base) / line_range); { char *a = format_dwarf_addr (dwflmod, 0, address, address); -- 1.9.3