diff options
author | Mark Wielaard <mark@klomp.org> | 2019-02-01 09:08:14 +0100 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2019-02-01 09:08:14 +0100 |
commit | cad9595592730fd8c9d0d9236d38f62ec8cfbcef (patch) | |
tree | eafd186a9011db0adb8a79ac13a87e54c3439e9b | |
parent | b63007ed58d23afdd64a4e77a447a12b64c5bced (diff) |
readelf: Check there is enough data to read DWARF line opcodes arguments.
When reading the debug_line opcode arguments we have to make sure there
is enough data to read the arguments (if there are any(.
The similar code in dwarf_getsrclines already had these checks.
https://sourceware.org/bugzilla/show_bug.cgi?id=24116
Signed-off-by: Mark Wielaard <mark@klomp.org>
-rw-r--r-- | src/readelf.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/readelf.c b/src/readelf.c index e3e699c4..33706bde 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -8703,7 +8703,8 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, case DW_LNE_set_discriminator: /* Takes one ULEB128 parameter, the discriminator. */ - if (unlikely (standard_opcode_lengths[opcode] != 1)) + if (unlikely (standard_opcode_lengths[opcode] != 1 + || lineendp - linep < 1)) goto invalid_unit; get_uleb128 (u128, linep, lineendp); @@ -8730,6 +8731,8 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, case DW_LNS_advance_pc: /* Takes one uleb128 parameter which is added to the address. */ + if (lineendp - linep < 1) + goto invalid_unit; get_uleb128 (u128, linep, lineendp); advance_pc (u128); { @@ -8745,6 +8748,8 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, case DW_LNS_advance_line: /* Takes one sleb128 parameter which is added to the line. */ + if (lineendp - linep < 1) + goto invalid_unit; get_sleb128 (s128, linep, lineendp); line += s128; printf (gettext ("\ @@ -8754,6 +8759,8 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, case DW_LNS_set_file: /* Takes one uleb128 parameter which is stored in file. */ + if (lineendp - linep < 1) + goto invalid_unit; get_uleb128 (u128, linep, lineendp); printf (gettext (" set file to %" PRIu64 "\n"), (uint64_t) u128); @@ -8761,7 +8768,8 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, case DW_LNS_set_column: /* Takes one uleb128 parameter which is stored in column. */ - if (unlikely (standard_opcode_lengths[opcode] != 1)) + if (unlikely (standard_opcode_lengths[opcode] != 1 + || lineendp - linep < 1)) goto invalid_unit; get_uleb128 (u128, linep, lineendp); @@ -8801,7 +8809,8 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, case DW_LNS_fixed_advance_pc: /* Takes one 16 bit parameter which is added to the address. */ - if (unlikely (standard_opcode_lengths[opcode] != 1)) + if (unlikely (standard_opcode_lengths[opcode] != 1 + || lineendp - linep < 2)) goto invalid_unit; u128 = read_2ubyte_unaligned_inc (dbg, linep); @@ -8828,7 +8837,8 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, case DW_LNS_set_isa: /* Takes one uleb128 parameter which is stored in isa. */ - if (unlikely (standard_opcode_lengths[opcode] != 1)) + if (unlikely (standard_opcode_lengths[opcode] != 1 + || lineendp - linep < 1)) goto invalid_unit; get_uleb128 (u128, linep, lineendp); |