diff options
author | Nick Clifton <nickc@redhat.com> | 2015-02-10 14:11:00 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2015-02-10 14:11:00 +0000 |
commit | 77ef86547510cee3a2bff27bea9f19f0b2715bae (patch) | |
tree | cf37b63c2505ce132ac49d286340751c4caebe7f /binutils | |
parent | b677c4562dea82ffaf413e7e9311ca4b9c1c6ec6 (diff) | |
download | gdb-77ef86547510cee3a2bff27bea9f19f0b2715bae.zip gdb-77ef86547510cee3a2bff27bea9f19f0b2715bae.tar.gz gdb-77ef86547510cee3a2bff27bea9f19f0b2715bae.tar.bz2 |
Fix memory access violations triggered by running objdump compiled with out-of-bounds sanitization checking.
PR binutils/17512
* dwarf.c (eh_addr_size): Use an unsigned type.
(size_of_encoded_value): Return an unsigned type.
(read_leb128): Break if the shift becomes too big.
(process_extended_line_op): Do not read the address if the length
is too long.
(read_cie): Warn and fail if the pointer size or segment size are
too big.
* dwarf.h (DWARF2_External_LineInfo): Delete unused and incorrect
structure definition.
(DWARF2_External_PubNames): Likewise.
(DWARF2_External_CompUnit): Likewise.
(DWARF2_External_ARange): Likewise.
(DWARF2_Internal_LineInfo): Use dwarf_vma type for
li_prologue_length.
(eh_addr_size): Update prototype.
* coffcode.h (styp_to_sec_flags): Use an unsigned long type to
hold the flag bits.
* peXXigen.c (pe_print_reloc): Use unsigned types to hold the
size and number of relocs.
(pe_print_debugdata): Use a 32-bit aligned buffer to store the
codeview record.
* versados.c (process_otr): Check the esdid value before using it
to access the EDATA.
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/ChangeLog | 19 | ||||
-rw-r--r-- | binutils/dwarf.c | 38 | ||||
-rw-r--r-- | binutils/dwarf.h | 46 |
3 files changed, 52 insertions, 51 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 01c4634..93cab73 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,22 @@ +2015-02-10 Nick Clifton <nickc@redhat.com> + + PR binutils/17512 + * dwarf.c (eh_addr_size): Use an unsigned type. + (size_of_encoded_value): Return an unsigned type. + (read_leb128): Break if the shift becomes too big. + (process_extended_line_op): Do not read the address if the length + is too long. + (read_cie): Warn and fail if the pointer size or segment size are + too big. + * dwarf.h (DWARF2_External_LineInfo): Delete unused and incorrect + structure definition. + (DWARF2_External_PubNames): Likewise. + (DWARF2_External_CompUnit): Likewise. + (DWARF2_External_ARange): Likewise. + (DWARF2_Internal_LineInfo): Use dwarf_vma type for + li_prologue_length. + (eh_addr_size): Update prototype. + 2015-02-09 Mark Wielaard <mjw@redhat.com> * dwarf.c (read_and_display_attr_value): Handle DW_LANG_Fortran03 diff --git a/binutils/dwarf.c b/binutils/dwarf.c index e93a757..9daf315 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -44,7 +44,7 @@ static debug_info *debug_information = NULL; that the .debug_info section could not be loaded/parsed. */ #define DEBUG_INFO_UNAVAILABLE (unsigned int) -1 -int eh_addr_size; +unsigned int eh_addr_size; int do_debug_info; int do_debug_abbrevs; @@ -105,7 +105,7 @@ static void load_cu_tu_indexes (void *file); #define FLAG_DEBUG_LINES_RAW 1 #define FLAG_DEBUG_LINES_DECODED 2 -static int +static unsigned int size_of_encoded_value (int encoding) { switch (encoding & 0x7) @@ -281,6 +281,11 @@ read_leb128 (unsigned char *data, shift += 7; if ((byte & 0x80) == 0) break; + + /* PR 17512: file: 0ca183b8. + FIXME: Should we signal this error somehow ? */ + if (shift >= sizeof (result)) + break; } if (length_return != NULL) @@ -446,9 +451,13 @@ process_extended_line_op (unsigned char * data, case DW_LNE_set_address: /* PR 17512: file: 002-100480-0.004. */ if (len - bytes_read - 1 > 8) - warn (_("Length (%d) of DW_LNE_set_address op is too long\n"), - len - bytes_read - 1); - SAFE_BYTE_GET (adr, data, len - bytes_read - 1, end); + { + warn (_("Length (%d) of DW_LNE_set_address op is too long\n"), + len - bytes_read - 1); + adr = 0; + } + else + SAFE_BYTE_GET (adr, data, len - bytes_read - 1, end); printf (_("set Address to 0x%s\n"), dwarf_vmatoa ("x", adr)); state_machine_regs.address = adr; state_machine_regs.op_index = 0; @@ -2860,7 +2869,7 @@ display_debug_lines_raw (struct dwarf_section *section, printf (_(" Offset: 0x%lx\n"), (long)(data - start)); printf (_(" Length: %ld\n"), (long) linfo.li_length); printf (_(" DWARF Version: %d\n"), linfo.li_version); - printf (_(" Prologue Length: %d\n"), linfo.li_prologue_length); + printf (_(" Prologue Length: %d\n"), (int) linfo.li_prologue_length); printf (_(" Minimum Instruction Length: %d\n"), linfo.li_min_insn_length); if (linfo.li_version >= 4) printf (_(" Maximum Ops per Instruction: %d\n"), linfo.li_max_ops_per_insn); @@ -2875,7 +2884,7 @@ display_debug_lines_raw (struct dwarf_section *section, warn (_("Line range of 0 is invalid, using 1 instead\n")); linfo.li_line_range = 1; } - + reset_state_machine (linfo.li_default_is_stmt); /* Display the contents of the Opcodes table. */ @@ -5542,7 +5551,20 @@ read_cie (unsigned char *start, unsigned char *end, if (version >= 4) { GET (fc->ptr_size, 1); + if (fc->ptr_size < 1 || fc->ptr_size > 8) + { + warn (_("Invalid pointer size (%d) in CIE data\n"), fc->ptr_size); + return end; + } + GET (fc->segment_size, 1); + /* PR 17512: file: e99d2804. */ + if (fc->segment_size > 8 || fc->segment_size + fc->ptr_size > 8) + { + warn (_("Invalid segment size (%d) in CIE data\n"), fc->segment_size); + return end; + } + eh_addr_size = fc->ptr_size; } else @@ -5634,7 +5656,7 @@ display_debug_frames (struct dwarf_section *section, unsigned int length_return; unsigned int max_regs = 0; const char *bad_reg = _("bad register: "); - int saved_eh_addr_size = eh_addr_size; + unsigned int saved_eh_addr_size = eh_addr_size; printf (_("Contents of the %s section:\n"), section->name); diff --git a/binutils/dwarf.h b/binutils/dwarf.h index 54dcbc7..45f9927 100644 --- a/binutils/dwarf.h +++ b/binutils/dwarf.h @@ -25,22 +25,9 @@ typedef unsigned HOST_WIDEST_INT dwarf_size_type; /* Structure found in the .debug_line section. */ typedef struct { - unsigned char li_length [4]; - unsigned char li_version [2]; - unsigned char li_prologue_length [4]; - unsigned char li_min_insn_length [1]; - unsigned char li_default_is_stmt [1]; - unsigned char li_line_base [1]; - unsigned char li_line_range [1]; - unsigned char li_opcode_base [1]; -} -DWARF2_External_LineInfo; - -typedef struct -{ dwarf_vma li_length; unsigned short li_version; - unsigned int li_prologue_length; + dwarf_vma li_prologue_length; unsigned char li_min_insn_length; unsigned char li_max_ops_per_insn; unsigned char li_default_is_stmt; @@ -53,15 +40,6 @@ DWARF2_Internal_LineInfo; /* Structure found in .debug_pubnames section. */ typedef struct { - unsigned char pn_length [4]; - unsigned char pn_version [2]; - unsigned char pn_offset [4]; - unsigned char pn_size [4]; -} -DWARF2_External_PubNames; - -typedef struct -{ dwarf_vma pn_length; unsigned short pn_version; dwarf_vma pn_offset; @@ -72,15 +50,6 @@ DWARF2_Internal_PubNames; /* Structure found in .debug_info section. */ typedef struct { - unsigned char cu_length [4]; - unsigned char cu_version [2]; - unsigned char cu_abbrev_offset [4]; - unsigned char cu_pointer_size [1]; -} -DWARF2_External_CompUnit; - -typedef struct -{ dwarf_vma cu_length; unsigned short cu_version; dwarf_vma cu_abbrev_offset; @@ -88,16 +57,7 @@ typedef struct } DWARF2_Internal_CompUnit; -typedef struct -{ - unsigned char ar_length [4]; - unsigned char ar_version [2]; - unsigned char ar_info_offset [4]; - unsigned char ar_pointer_size [1]; - unsigned char ar_segment_size [1]; -} -DWARF2_External_ARange; - +/* Structure found in .debug_aranges section. */ typedef struct { dwarf_vma ar_length; @@ -207,7 +167,7 @@ typedef struct } debug_info; -extern int eh_addr_size; +extern unsigned int eh_addr_size; extern int do_debug_info; extern int do_debug_abbrevs; |