Fix memory access violations triggered by running addr2line on fuzzed binaries.

PR binutils/17512
	* dwarf.c (read_1_byte, read_1_signed_byte, read_2_bytes)
	(read_4_bytes, read_8_bytes, read_n_bytes, read_string)
	(read_indirect_string, read_alt_indirect_string)
	(read_alt_indirect_ref, read_address, read_abbrevs)
	(read_attribute_value, read_attribute, decode_line_info)
	(find_abstract_instance_name, read_rangelist)
	(scan_unit_for_symbols, parse_comp_unit)
	(_bfd_dwarf2_find_nearest_line): Harden DWARF reading code.  Pass
	end pointers to reading functions and check for offsets taking
	pointers out of range.  Replace calls to read_*_leb128 with calls
	to safe_read_leb128.

	(* elf64-ppc.c (opd_entry_value): Add a check for an overlarge
	offset.
	* syms.c (_bfd_stab_section_find_nearest_line): Add checks for
	computed file_name address being before the start of the string
	table.
This commit is contained in:
Nick Clifton
2015-02-12 16:45:11 +00:00
parent 0e7f931f3a
commit dbb3fbbb1a
4 changed files with 311 additions and 137 deletions

View File

@@ -1192,7 +1192,7 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
{
nul_fun = stab;
nul_str = str;
if (file_name >= (char *) info->strs + strsize)
if (file_name >= (char *) info->strs + strsize || file_name < (char *) str)
file_name = NULL;
if (stab + STABSIZE + TYPEOFF < info->stabs + stabsize
&& *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
@@ -1203,7 +1203,7 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
directory_name = file_name;
file_name = ((char *) str
+ bfd_get_32 (abfd, stab + STRDXOFF));
if (file_name >= (char *) info->strs + strsize)
if (file_name >= (char *) info->strs + strsize || file_name < (char *) str)
file_name = NULL;
}
}
@@ -1213,7 +1213,8 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
/* The name of an include file. */
file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
/* PR 17512: file: 0c680a1f. */
if (file_name >= (char *) info->strs + strsize)
/* PR 17512: file: 5da8aec4. */
if (file_name >= (char *) info->strs + strsize || file_name < (char *) str)
file_name = NULL;
break;
@@ -1331,7 +1332,7 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
if (val <= offset)
{
file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
if (file_name >= (char *) info->strs + strsize)
if (file_name >= (char *) info->strs + strsize || file_name < (char *) str)
file_name = NULL;
*pline = 0;
}