• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revision362beea4b400bcd5aca3bb1215a77e9e749b07fe (tree)
Time2015-02-11 22:05:04
AuthorNick Clifton <nickc@redh...>
CommiterNick Clifton

Log Message

Fixes for invalid memory accesses triggered by running readelf on fuzzed binaries.

PR binutils/17531
* dwarf.c (display_debug_pubnames_worker): Work around compiler
bug checking address ranges.
(display_debug_frames): Likewise.
(display_gdb_index): Likewise.
(process_cu_tu_index): Add range check on the ncols value.

Change Summary

Incremental Difference

--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,12 @@
1+2015-02-11 Nick Clifton <nickc@redhat.com>
2+
3+ PR binutils/17531
4+ * dwarf.c (display_debug_pubnames_worker): Work around compiler
5+ bug checking address ranges.
6+ (display_debug_frames): Likewise.
7+ (display_gdb_index): Likewise.
8+ (process_cu_tu_index): Add range check on the ncols value.
9+
110 2015-02-10 Nick Clifton <nickc@redhat.com>
211
312 PR binutils/17512
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -3725,6 +3725,7 @@ display_debug_pubnames_worker (struct dwarf_section *section,
37253725 while (start < end)
37263726 {
37273727 unsigned char *data;
3728+ unsigned char *adr;
37283729 dwarf_vma offset;
37293730 unsigned int offset_size, initial_length_size;
37303731
@@ -3754,17 +3755,18 @@ display_debug_pubnames_worker (struct dwarf_section *section,
37543755
37553756 SAFE_BYTE_GET_AND_INC (names.pn_size, data, offset_size, end);
37563757
3758+ adr = start + names.pn_length + initial_length_size;
37573759 /* PR 17531: file: 7615b6b2. */
37583760 if ((dwarf_signed_vma) names.pn_length < 0
37593761 /* PR 17531: file: a5dbeaa7. */
3760- || start + names.pn_length + initial_length_size < start)
3762+ || adr < start)
37613763 {
37623764 warn (_("Negative length for public name: 0x%lx\n"), (long) names.pn_length);
37633765 start = end;
37643766 }
37653767 else
3766- start += names.pn_length + initial_length_size;
3767-
3768+ start = adr;
3769+
37683770 printf (_(" Length: %ld\n"),
37693771 (long) names.pn_length);
37703772 printf (_(" Version: %d\n"),
@@ -6111,6 +6113,7 @@ display_debug_frames (struct dwarf_section *section,
61116113
61126114 while (start < block_end)
61136115 {
6116+ unsigned char * tmp;
61146117 unsigned op, opa;
61156118 unsigned long ul, reg, roffs;
61166119 long l;
@@ -6412,7 +6415,8 @@ display_debug_frames (struct dwarf_section *section,
64126415 reg_prefix = bad_reg;
64136416 /* PR 17512: file: 069-133014-0.006. */
64146417 /* PR 17512: file: 98c02eb4. */
6415- if (start >= block_end || start + ul > block_end || start + ul < start)
6418+ tmp = start + ul;
6419+ if (start >= block_end || tmp > block_end || tmp < start)
64166420 {
64176421 printf (_(" DW_CFA_expression: <corrupt len %lu>\n"), ul);
64186422 break;
@@ -6427,7 +6431,7 @@ display_debug_frames (struct dwarf_section *section,
64276431 }
64286432 if (*reg_prefix == '\0')
64296433 fc->col_type[reg] = DW_CFA_expression;
6430- start += ul;
6434+ start = tmp;
64316435 break;
64326436
64336437 case DW_CFA_val_expression:
@@ -6435,7 +6439,8 @@ display_debug_frames (struct dwarf_section *section,
64356439 ul = LEB ();
64366440 if (reg >= (unsigned int) fc->ncols)
64376441 reg_prefix = bad_reg;
6438- if (start >= block_end || start + ul > block_end || start + ul < start)
6442+ tmp = start + ul;
6443+ if (start >= block_end || tmp > block_end || tmp < start)
64396444 {
64406445 printf (" DW_CFA_val_expression: <corrupt len %lu>\n", ul);
64416446 break;
@@ -6450,7 +6455,7 @@ display_debug_frames (struct dwarf_section *section,
64506455 }
64516456 if (*reg_prefix == '\0')
64526457 fc->col_type[reg] = DW_CFA_val_expression;
6453- start += ul;
6458+ start = tmp;
64546459 break;
64556460
64566461 case DW_CFA_offset_extended_sf:
@@ -6729,10 +6734,11 @@ display_gdb_index (struct dwarf_section *section,
67296734 || cu_vector_offset != 0)
67306735 {
67316736 unsigned int j;
6737+ unsigned char * adr;
67326738
6739+ adr = constant_pool + name_offset;
67336740 /* PR 17531: file: 5b7b07ad. */
6734- if (constant_pool + name_offset < constant_pool
6735- || constant_pool + name_offset >= section->start + section->size)
6741+ if (adr < constant_pool || adr >= section->start + section->size)
67366742 {
67376743 printf (_("[%3u] <corrupt offset: %x>"), i, name_offset);
67386744 warn (_("Corrupt name offset of 0x%x found for symbol table slot %d\n"),
@@ -6743,8 +6749,8 @@ display_gdb_index (struct dwarf_section *section,
67436749 (int) (section->size - (constant_pool_offset + name_offset)),
67446750 constant_pool + name_offset);
67456751
6746- if (constant_pool + cu_vector_offset < constant_pool
6747- || constant_pool + cu_vector_offset >= section->start + section->size - 3)
6752+ adr = constant_pool + cu_vector_offset;
6753+ if (adr < constant_pool || adr >= section->start + section->size - 3)
67486754 {
67496755 printf (_("<invalid CU vector offset: %x>\n"), cu_vector_offset);
67506756 warn (_("Corrupt CU vector offset of 0x%x found for symbol table slot %d\n"),
@@ -6752,12 +6758,12 @@ display_gdb_index (struct dwarf_section *section,
67526758 continue;
67536759 }
67546760
6755- num_cus = byte_get_little_endian (constant_pool + cu_vector_offset, 4);
6761+ num_cus = byte_get_little_endian (adr, 4);
67566762
6763+ adr = constant_pool + cu_vector_offset + 4 + num_cus * 4;
67576764 if (num_cus * 4 < num_cus
6758- || constant_pool + cu_vector_offset + 4 + num_cus * 4
6759- >= section->start + section->size
6760- || (constant_pool + cu_vector_offset + 4 + num_cus * 4) < constant_pool)
6765+ || adr >= section->start + section->size
6766+ || adr < constant_pool)
67616767 {
67626768 printf ("<invalid number of CUs: %d>\n", num_cus);
67636769 warn (_("Invalid number of CUs (0x%x) for symbol table slot %d\n"),
@@ -7011,6 +7017,14 @@ process_cu_tu_index (struct dwarf_section *section, int do_display)
70117017
70127018 is_tu_index = strcmp (section->name, ".debug_tu_index") == 0;
70137019
7020+ /* PR 17531: file: 0dd159bf.
7021+ Check for wraparound with an overlarge ncols value. */
7022+ if ((unsigned int) ((poffsets - ppool) / 4) != ncols)
7023+ {
7024+ warn (_("Overlarge number of columns: %x\n"), ncols);
7025+ return 0;
7026+ }
7027+
70147028 if (pend > limit)
70157029 {
70167030 warn (_("Section %s too small for offset and size tables\n"),