aboutsummaryrefslogtreecommitdiff
path: root/binutils/dwarf.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-02-26 14:21:54 +0000
committerNick Clifton <nickc@redhat.com>2015-02-26 14:23:27 +0000
commitc8071705c69a13d237aeca4709bf91deaff7e5cb (patch)
treed176a0f3d8569bb1a6a8d05686dbaa878fee1a54 /binutils/dwarf.c
parent03eddd80d7c9b406109c43c07741c9991520954b (diff)
downloadgdb-c8071705c69a13d237aeca4709bf91deaff7e5cb.zip
gdb-c8071705c69a13d237aeca4709bf91deaff7e5cb.tar.gz
gdb-c8071705c69a13d237aeca4709bf91deaff7e5cb.tar.bz2
Fix undefined arithmetic operations detected by -fsanitize=undefined when running readelf on fuzzed binaries.
PR binutils/17512 * dwarf.c (display_debug_loc): Pacify the undefined behaviour sanitizer by simplifying address difference calculation. (struct Frame_Chunk): Change type of cfa_offset to dwarf_vma in order to avoid arithmetic overflows. (frame_display_row): Cast cfa_offset before printing it. (display_debug_frames): Likewise. Check for an unexpected segment size. Chnage type of 'l' local to dwarf_vma and cast it back to an int when printing. (process_cu_tu_index): Tighten check for an invalid ncols value. * readelf.c (process_corefile_note_segment): Check for inote.descdata extending beyond the end of the section. (process_v850_notes): Likewise.
Diffstat (limited to 'binutils/dwarf.c')
-rw-r--r--binutils/dwarf.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 272b41f..5884140 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -4719,11 +4719,11 @@ display_debug_loc (struct dwarf_section *section, void *file)
if (start < next)
warn (_("There is a hole [0x%lx - 0x%lx] in .debug_loc section.\n"),
(unsigned long) (start - section_begin),
- (unsigned long) (next - section_begin));
+ (unsigned long) offset);
else if (start > next)
warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_loc section.\n"),
(unsigned long) (start - section_begin),
- (unsigned long) (next - section_begin));
+ (unsigned long) offset);
}
start = next;
@@ -5244,7 +5244,7 @@ typedef struct Frame_Chunk
dwarf_vma pc_begin;
dwarf_vma pc_range;
int cfa_reg;
- int cfa_offset;
+ dwarf_vma cfa_offset;
unsigned int ra;
unsigned char fde_encoding;
unsigned char cfa_exp;
@@ -5481,7 +5481,7 @@ frame_display_row (Frame_Chunk *fc, int *need_col_headers, unsigned int *max_reg
if (fc->cfa_exp)
strcpy (tmp, "exp");
else
- sprintf (tmp, "%s%+d", regname (fc->cfa_reg, 1), fc->cfa_offset);
+ sprintf (tmp, "%s%+d", regname (fc->cfa_reg, 1), (int) fc->cfa_offset);
printf ("%-8s ", tmp);
for (r = 0; r < fc->ncols; r++)
@@ -5921,7 +5921,15 @@ display_debug_frames (struct dwarf_section *section,
segment_selector = 0;
if (fc->segment_size)
- SAFE_BYTE_GET_AND_INC (segment_selector, start, fc->segment_size, end);
+ {
+ if (fc->segment_size > sizeof (segment_selector))
+ {
+ /* PR 17512: file: 9e196b3e. */
+ warn (_("Probably corrupt segment size: %d - using 4 instead\n"), fc->segment_size);
+ fc->segment_size = 4;
+ }
+ SAFE_BYTE_GET_AND_INC (segment_selector, start, fc->segment_size, end);
+ }
fc->pc_begin = get_encoded_value (&start, fc->fde_encoding, section, end);
@@ -6123,7 +6131,7 @@ display_debug_frames (struct dwarf_section *section,
unsigned char * tmp;
unsigned op, opa;
unsigned long ul, reg, roffs;
- long l;
+ dwarf_vma l;
dwarf_vma ofs;
dwarf_vma vma;
const char *reg_prefix = "";
@@ -6375,7 +6383,7 @@ display_debug_frames (struct dwarf_section *section,
fc->cfa_exp = 0;
if (! do_debug_frames_interp)
printf (" DW_CFA_def_cfa: %s ofs %d\n",
- regname (fc->cfa_reg, 0), fc->cfa_offset);
+ regname (fc->cfa_reg, 0), (int) fc->cfa_offset);
break;
case DW_CFA_def_cfa_register:
@@ -6389,7 +6397,7 @@ display_debug_frames (struct dwarf_section *section,
case DW_CFA_def_cfa_offset:
fc->cfa_offset = LEB ();
if (! do_debug_frames_interp)
- printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
+ printf (" DW_CFA_def_cfa_offset: %d\n", (int) fc->cfa_offset);
break;
case DW_CFA_nop:
@@ -6473,7 +6481,7 @@ display_debug_frames (struct dwarf_section *section,
if (! do_debug_frames_interp || *reg_prefix != '\0')
printf (" DW_CFA_offset_extended_sf: %s%s at cfa%+ld\n",
reg_prefix, regname (reg, 0),
- l * fc->data_factor);
+ (long)(l * fc->data_factor));
if (*reg_prefix == '\0')
{
fc->col_type[reg] = DW_CFA_offset;
@@ -6489,7 +6497,7 @@ display_debug_frames (struct dwarf_section *section,
if (! do_debug_frames_interp || *reg_prefix != '\0')
printf (" DW_CFA_val_offset_sf: %s%s at cfa%+ld\n",
reg_prefix, regname (reg, 0),
- l * fc->data_factor);
+ (long)(l * fc->data_factor));
if (*reg_prefix == '\0')
{
fc->col_type[reg] = DW_CFA_val_offset;
@@ -6504,14 +6512,14 @@ display_debug_frames (struct dwarf_section *section,
fc->cfa_exp = 0;
if (! do_debug_frames_interp)
printf (" DW_CFA_def_cfa_sf: %s ofs %d\n",
- regname (fc->cfa_reg, 0), fc->cfa_offset);
+ regname (fc->cfa_reg, 0), (int) fc->cfa_offset);
break;
case DW_CFA_def_cfa_offset_sf:
fc->cfa_offset = SLEB ();
- fc->cfa_offset = fc->cfa_offset * fc->data_factor;
+ fc->cfa_offset *= fc->data_factor;
if (! do_debug_frames_interp)
- printf (" DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
+ printf (" DW_CFA_def_cfa_offset_sf: %d\n", (int) fc->cfa_offset);
break;
case DW_CFA_MIPS_advance_loc8:
@@ -6546,7 +6554,7 @@ display_debug_frames (struct dwarf_section *section,
if (! do_debug_frames_interp || *reg_prefix != '\0')
printf (" DW_CFA_GNU_negative_offset_extended: %s%s at cfa%+ld\n",
reg_prefix, regname (reg, 0),
- l * fc->data_factor);
+ (long)(l * fc->data_factor));
if (*reg_prefix == '\0')
{
fc->col_type[reg] = DW_CFA_offset;
@@ -7026,7 +7034,7 @@ process_cu_tu_index (struct dwarf_section *section, int do_display)
/* PR 17531: file: 0dd159bf.
Check for wraparound with an overlarge ncols value. */
- if ((unsigned int) ((poffsets - ppool) / 4) != ncols)
+ if (poffsets < ppool || (unsigned int) ((poffsets - ppool) / 4) != ncols)
{
warn (_("Overlarge number of columns: %x\n"), ncols);
return 0;