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.
This commit is contained in:
parent
b677c4562d
commit
77ef865475
@ -1,3 +1,15 @@
|
||||
2015-02-10 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR binutils/17512
|
||||
* 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.
|
||||
|
||||
2015-02-09 Ed Maste <emaste@freebsd.org>
|
||||
|
||||
* elf32-i386.c (elf_i386_get_plt_sym_val): Avoid incrementing
|
||||
|
@ -1169,7 +1169,7 @@ styp_to_sec_flags (bfd *abfd,
|
||||
flagword *flags_ptr)
|
||||
{
|
||||
struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
|
||||
long styp_flags = internal_s->s_flags;
|
||||
unsigned long styp_flags = internal_s->s_flags;
|
||||
flagword sec_flags;
|
||||
bfd_boolean result = TRUE;
|
||||
bfd_boolean is_dbg = FALSE;
|
||||
@ -1192,7 +1192,7 @@ styp_to_sec_flags (bfd *abfd,
|
||||
/* Process each flag bit in styp_flags in turn. */
|
||||
while (styp_flags)
|
||||
{
|
||||
long flag = styp_flags & - styp_flags;
|
||||
unsigned long flag = styp_flags & - styp_flags;
|
||||
char * unhandled = NULL;
|
||||
|
||||
styp_flags &= ~ flag;
|
||||
|
@ -1151,7 +1151,7 @@ _bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length
|
||||
/* Ensure null termination of filename. */
|
||||
buffer[256] = '\0';
|
||||
|
||||
cvinfo->CVSignature = H_GET_32(abfd, buffer);
|
||||
cvinfo->CVSignature = H_GET_32 (abfd, buffer);
|
||||
cvinfo->Age = 0;
|
||||
|
||||
if ((cvinfo->CVSignature == CVINFO_PDB70_CVSIGNATURE)
|
||||
@ -2216,7 +2216,7 @@ pe_print_reloc (bfd * abfd, void * vfile)
|
||||
{
|
||||
int j;
|
||||
bfd_vma virtual_address;
|
||||
long number, size;
|
||||
unsigned long number, size;
|
||||
bfd_byte *chunk_end;
|
||||
|
||||
/* The .reloc section is a sequence of blocks, with a header consisting
|
||||
@ -2231,7 +2231,7 @@ pe_print_reloc (bfd * abfd, void * vfile)
|
||||
|
||||
fprintf (file,
|
||||
_("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
|
||||
(unsigned long) virtual_address, size, (unsigned long) size, number);
|
||||
(unsigned long) virtual_address, size, size, number);
|
||||
|
||||
chunk_end = p + size;
|
||||
if (chunk_end > end)
|
||||
@ -2674,7 +2674,11 @@ pe_print_debugdata (bfd * abfd, void * vfile)
|
||||
if (idd.Type == PE_IMAGE_DEBUG_TYPE_CODEVIEW)
|
||||
{
|
||||
char signature[CV_INFO_SIGNATURE_LENGTH * 2 + 1];
|
||||
char buffer[256 + 1];
|
||||
/* PR 17512: file: 065-29434-0.001:0.1
|
||||
We need to use a 32-bit aligned buffer
|
||||
to safely read in a codeview record. */
|
||||
char buffer[256 + 1] ATTRIBUTE_ALIGNED_ALIGNOF (CODEVIEW_INFO);
|
||||
|
||||
CODEVIEW_INFO *cvinfo = (CODEVIEW_INFO *) buffer;
|
||||
|
||||
/* The debug entry doesn't have to have to be in a section,
|
||||
|
@ -373,7 +373,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
|
||||
| (otr->map[2] << 8)
|
||||
| (otr->map[3] << 0);
|
||||
|
||||
struct esdid *esdid = &EDATA (abfd, otr->esdid - 1);
|
||||
struct esdid *esdid;
|
||||
unsigned char *contents;
|
||||
bfd_boolean need_contents = FALSE;
|
||||
unsigned int dst_idx;
|
||||
@ -382,6 +382,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
|
||||
if (otr->esdid == 0)
|
||||
return;
|
||||
|
||||
esdid = &EDATA (abfd, otr->esdid - 1);
|
||||
contents = esdid->contents;
|
||||
dst_idx = esdid->pc;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -23,24 +23,11 @@ typedef HOST_WIDEST_INT dwarf_signed_vma;
|
||||
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;
|
||||
@ -51,15 +38,6 @@ typedef struct
|
||||
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;
|
||||
@ -70,15 +48,6 @@ typedef struct
|
||||
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;
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user