• 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

Revisão896ca0981329171639b1fe0b934393a79ef4fdfb (tree)
Hora2015-01-06 08:13:50
AutorNick Clifton <nickc@redh...>
CommiterNick Clifton

Mensagem de Log

More fixes for invalid memory accesses triggered by fuzzed binaries.

PR binutils/17512
* nm.c (print_symbol): Add 'is_synthetic' parameter. Use it to
help initialize the info.elfinfo field.
(print_size_symbols): Add 'synth_count' parameter. Use it to set
the is_synthetic parameter when calling print_symbol.
(print_symbols): Likewise.
(display_rel_file): Pass synth_count to printing function.
(display_archive): Break loop if the last archive displayed
matches the current archive.
* size.c (display_archive): Likewise.

* archive.c (do_slurp_bsd_armap): Make sure that the parsed sized
is at least big enough for the header to be read.
* elf32-i386.c (elf_i386_get_plt_sym_val): Skip unknown relocs.
* mach-o.c (bfd_mach_o_get_synthetic_symtab): Add range checks.
(bfd_mach_o_read_command): Prevetn duplicate error messages about
unrecognized commands.
* syms.c (_bfd_stab_section_find_nearest_line): Add range checks
when indexing into the string table.

Mudança Sumário

Diff

--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
1+2015-01-05 Nick Clifton <nickc@redhat.com>
2+
3+ PR binutils/17512
4+ * archive.c (do_slurp_bsd_armap): Make sure that the parsed sized
5+ is at least big enough for the header to be read.
6+ * elf32-i386.c (elf_i386_get_plt_sym_val): Skip unknown relocs.
7+ * mach-o.c (bfd_mach_o_get_synthetic_symtab): Add range checks.
8+ (bfd_mach_o_read_command): Prevetn duplicate error messages about
9+ unrecognized commands.
10+ * syms.c (_bfd_stab_section_find_nearest_line): Add range checks
11+ when indexing into the string table.
12+
113 2015-01-01 Alan Modra <amodra@gmail.com>
214
315 Update year range in copyright notice of all files.
--- a/bfd/archive.c
+++ b/bfd/archive.c
@@ -903,7 +903,8 @@ do_slurp_bsd_armap (bfd *abfd)
903903 parsed_size = mapdata->parsed_size;
904904 free (mapdata);
905905 /* PR 17512: file: 883ff754. */
906- if (parsed_size == 0)
906+ /* PR 17512: file: 0458885f. */
907+ if (parsed_size < 4)
907908 return FALSE;
908909
909910 raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size);
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -5194,8 +5194,9 @@ bad_return:
51945194 {
51955195 long reloc_index;
51965196
5197- if (p->howto->type != R_386_JUMP_SLOT
5198- && p->howto->type != R_386_IRELATIVE)
5197+ if (p->howto == NULL /* PR 17512: file: bc9d6cf5. */
5198+ || (p->howto->type != R_386_JUMP_SLOT
5199+ && p->howto->type != R_386_IRELATIVE))
51995200 continue;
52005201
52015202 reloc_index = H_GET_32 (abfd, (plt_contents + plt_offset
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -1214,10 +1214,9 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
12141214 for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++)
12151215 {
12161216 memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));
1217- sym->symbol.the_bfd = abfd;
12181217
1218+ sym->symbol.the_bfd = abfd;
12191219 sym->symbol.name = bfd_elf_sym_name (abfd, hdr, isym, NULL);
1220-
12211220 sym->symbol.value = isym->st_value;
12221221
12231222 if (isym->st_shndx == SHN_UNDEF)
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -790,18 +790,19 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
790790 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
791791 bfd_mach_o_symtab_command *symtab = mdata->symtab;
792792 asymbol *s;
793+ char * s_start;
794+ char * s_end;
793795 unsigned long count, i, j, n;
794796 size_t size;
795797 char *names;
796798 char *nul_name;
799+ const char stub [] = "$stub";
797800
798801 *ret = NULL;
799802
800803 /* Stop now if no symbols or no indirect symbols. */
801- if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL)
802- return 0;
803-
804- if (dysymtab->nindirectsyms == 0)
804+ if (dysymtab == NULL || dysymtab->nindirectsyms == 0
805+ || symtab == NULL || symtab->symbols == NULL)
805806 return 0;
806807
807808 /* We need to allocate a bfd symbol for every indirect symbol and to
@@ -811,19 +812,23 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
811812
812813 for (j = 0; j < count; j++)
813814 {
815+ const char * strng;
814816 unsigned int isym = dysymtab->indirect_syms[j];
815817
816818 /* Some indirect symbols are anonymous. */
817- if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name)
818- size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub");
819+ if (isym < symtab->nsyms && (strng = symtab->symbols[isym].symbol.name))
820+ /* PR 17512: file: f5b8eeba. */
821+ size += strnlen (strng, symtab->strsize - (strng - symtab->strtab)) + sizeof (stub);
819822 }
820823
821- s = *ret = (asymbol *) bfd_malloc (size);
824+ s_start = bfd_malloc (size);
825+ s = *ret = (asymbol *) s_start;
822826 if (s == NULL)
823827 return -1;
824828 names = (char *) (s + count);
825829 nul_name = names;
826830 *names++ = 0;
831+ s_end = s_start + size;
827832
828833 n = 0;
829834 for (i = 0; i < mdata->nsects; i++)
@@ -843,10 +848,19 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
843848 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
844849 addr = sec->addr;
845850 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
851+
852+ /* PR 17512: file: 08e15eec. */
853+ if (first >= count || last >= count || first > last)
854+ goto fail;
855+
846856 for (j = first; j < last; j++)
847857 {
848858 unsigned int isym = dysymtab->indirect_syms[j];
849859
860+ /* PR 17512: file: 04d64d9b. */
861+ if (((char *) s) + sizeof (* s) > s_end)
862+ goto fail;
863+
850864 s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
851865 s->section = sec->bfdsection;
852866 s->value = addr - sec->addr;
@@ -860,10 +874,16 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
860874
861875 s->name = names;
862876 len = strlen (sym);
877+ /* PR 17512: file: 47dfd4d2. */
878+ if (names + len >= s_end)
879+ goto fail;
863880 memcpy (names, sym, len);
864881 names += len;
865- memcpy (names, "$stub", sizeof ("$stub"));
866- names += sizeof ("$stub");
882+ /* PR 17512: file: 18f340a4. */
883+ if (names + sizeof (stub) >= s_end)
884+ goto fail;
885+ memcpy (names, stub, sizeof (stub));
886+ names += sizeof (stub);
867887 }
868888 else
869889 s->name = nul_name;
@@ -879,6 +899,11 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
879899 }
880900
881901 return n;
902+
903+ fail:
904+ free (s_start);
905+ * ret = NULL;
906+ return -1;
882907 }
883908
884909 void
@@ -4660,9 +4685,21 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
46604685 return FALSE;
46614686 break;
46624687 default:
4663- (*_bfd_error_handler)(_("%B: unknown load command 0x%lx"),
4664- abfd, (unsigned long) command->type);
4665- break;
4688+ {
4689+ static bfd_boolean unknown_set = FALSE;
4690+ static unsigned long unknown_command = 0;
4691+
4692+ /* Prevent reams of error messages when parsing corrupt binaries. */
4693+ if (!unknown_set)
4694+ unknown_set = TRUE;
4695+ else if (command->type == unknown_command)
4696+ break;
4697+ unknown_command = command->type;
4698+
4699+ (*_bfd_error_handler)(_("%B: unknown load command 0x%lx"),
4700+ abfd, (unsigned long) command->type);
4701+ break;
4702+ }
46664703 }
46674704
46684705 return TRUE;
--- a/bfd/syms.c
+++ b/bfd/syms.c
@@ -823,6 +823,7 @@ _bfd_generic_read_minisymbols (bfd *abfd,
823823
824824 *minisymsp = syms;
825825 *sizep = sizeof (asymbol *);
826+
826827 return symcount;
827828
828829 error_return:
@@ -1191,6 +1192,8 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
11911192 {
11921193 nul_fun = stab;
11931194 nul_str = str;
1195+ if (file_name >= (char *) info->strs + strsize)
1196+ file_name = NULL;
11941197 if (stab + STABSIZE + TYPEOFF < info->stabs + stabsize
11951198 && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
11961199 {
@@ -1200,6 +1203,8 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
12001203 directory_name = file_name;
12011204 file_name = ((char *) str
12021205 + bfd_get_32 (abfd, stab + STRDXOFF));
1206+ if (file_name >= (char *) info->strs + strsize)
1207+ file_name = NULL;
12031208 }
12041209 }
12051210 break;
@@ -1207,6 +1212,9 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
12071212 case N_SOL:
12081213 /* The name of an include file. */
12091214 file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
1215+ /* PR 17512: file: 0c680a1f. */
1216+ if (file_name >= (char *) info->strs + strsize)
1217+ file_name = NULL;
12101218 break;
12111219
12121220 case N_FUN:
@@ -1214,6 +1222,8 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
12141222 function_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
12151223 if (function_name == (char *) str)
12161224 continue;
1225+ if (function_name >= (char *) info->strs + strsize)
1226+ function_name = NULL;
12171227
12181228 nul_fun = NULL;
12191229 info->indextable[i].val = bfd_get_32 (abfd, stab + VALOFF);
@@ -1321,6 +1331,8 @@ _bfd_stab_section_find_nearest_line (bfd *abfd,
13211331 if (val <= offset)
13221332 {
13231333 file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
1334+ if (file_name >= (char *) info->strs + strsize)
1335+ file_name = NULL;
13241336 *pline = 0;
13251337 }
13261338 break;
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,18 @@
11 2015-01-05 Nick Clifton <nickc@redhat.com>
22
3+ PR binutils/17512
4+ * nm.c (print_symbol): Add 'is_synthetic' parameter. Use it to
5+ help initialize the info.elfinfo field.
6+ (print_size_symbols): Add 'synth_count' parameter. Use it to set
7+ the is_synthetic parameter when calling print_symbol.
8+ (print_symbols): Likewise.
9+ (display_rel_file): Pass synth_count to printing function.
10+ (display_archive): Break loop if the last archive displayed
11+ matches the current archive.
12+ * size.c (display_archive): Likewise.
13+
14+2015-01-05 Nick Clifton <nickc@redhat.com>
15+
316 PR binutils/17531
417 * dwarf.c (alloc_num_debug_info_entries): New variable.
518 (process_debug_info): Set it. Use it to avoid displaying
--- a/binutils/nm.c
+++ b/binutils/nm.c
@@ -806,7 +806,11 @@ get_relocs (bfd *abfd, asection *sec, void *dataarg)
806806 /* Print a single symbol. */
807807
808808 static void
809-print_symbol (bfd *abfd, asymbol *sym, bfd_vma ssize, bfd *archive_bfd)
809+print_symbol (bfd * abfd,
810+ asymbol * sym,
811+ bfd_vma ssize,
812+ bfd * archive_bfd,
813+ bfd_boolean is_synthetic)
810814 {
811815 symbol_info syminfo;
812816 struct extended_symbol_info info;
@@ -816,12 +820,12 @@ print_symbol (bfd *abfd, asymbol *sym, bfd_vma ssize, bfd *archive_bfd)
816820 format->print_symbol_filename (archive_bfd, abfd);
817821
818822 bfd_get_symbol_info (abfd, sym, &syminfo);
823+
819824 info.sinfo = &syminfo;
820825 info.ssize = ssize;
821- if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
822- info.elfinfo = (elf_symbol_type *) sym;
823- else
824- info.elfinfo = NULL;
826+ /* Synthetic symbols do not have a full elf_symbol_type set of data available. */
827+ info.elfinfo = is_synthetic ? NULL : elf_symbol_from (abfd, sym);
828+
825829 format->print_symbol_info (&info, abfd);
826830
827831 if (line_numbers)
@@ -941,12 +945,17 @@ print_symbol (bfd *abfd, asymbol *sym, bfd_vma ssize, bfd *archive_bfd)
941945 /* Print the symbols when sorting by size. */
942946
943947 static void
944-print_size_symbols (bfd *abfd, bfd_boolean is_dynamic,
945- struct size_sym *symsizes, long symcount,
946- bfd *archive_bfd)
948+print_size_symbols (bfd * abfd,
949+ bfd_boolean is_dynamic,
950+ struct size_sym * symsizes,
951+ long symcount,
952+ long synth_count,
953+ bfd * archive_bfd)
947954 {
948955 asymbol *store;
949- struct size_sym *from, *fromend;
956+ struct size_sym *from;
957+ struct size_sym *fromend;
958+ struct size_sym *fromsynth;
950959
951960 store = bfd_make_empty_symbol (abfd);
952961 if (store == NULL)
@@ -954,6 +963,8 @@ print_size_symbols (bfd *abfd, bfd_boolean is_dynamic,
954963
955964 from = symsizes;
956965 fromend = from + symcount;
966+ fromsynth = symsizes + (symcount - synth_count);
967+
957968 for (; from < fromend; from++)
958969 {
959970 asymbol *sym;
@@ -962,20 +973,34 @@ print_size_symbols (bfd *abfd, bfd_boolean is_dynamic,
962973 if (sym == NULL)
963974 bfd_fatal (bfd_get_filename (abfd));
964975
965- print_symbol (abfd, sym, from->size, archive_bfd);
976+ print_symbol (abfd, sym, from->size, archive_bfd, from >= fromsynth);
966977 }
967978 }
968979
969980
970-/* Print the symbols. If ARCHIVE_BFD is non-NULL, it is the archive
971- containing ABFD. */
981+/* Print the symbols of ABFD that are held in MINISYMS.
982+
983+ If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD.
984+
985+ SYMCOUNT is the number of symbols in MINISYMS and SYNTH_COUNT
986+ is the number of these that are synthetic. Synthetic symbols,
987+ if any are present, always come at the end of the MINISYMS.
988+
989+ SIZE is the size of a symbol in MINISYMS. */
972990
973991 static void
974-print_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, long symcount,
975- unsigned int size, bfd *archive_bfd)
992+print_symbols (bfd * abfd,
993+ bfd_boolean is_dynamic,
994+ void * minisyms,
995+ long symcount,
996+ long synth_count,
997+ unsigned int size,
998+ bfd * archive_bfd)
976999 {
9771000 asymbol *store;
978- bfd_byte *from, *fromend;
1001+ bfd_byte *from;
1002+ bfd_byte *fromend;
1003+ bfd_byte *fromsynth;
9791004
9801005 store = bfd_make_empty_symbol (abfd);
9811006 if (store == NULL)
@@ -983,6 +1008,8 @@ print_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, long symcount,
9831008
9841009 from = (bfd_byte *) minisyms;
9851010 fromend = from + symcount * size;
1011+ fromsynth = (bfd_byte *) minisyms + ((symcount - synth_count) * size);
1012+
9861013 for (; from < fromend; from += size)
9871014 {
9881015 asymbol *sym;
@@ -991,7 +1018,7 @@ print_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, long symcount,
9911018 if (sym == NULL)
9921019 bfd_fatal (bfd_get_filename (abfd));
9931020
994- print_symbol (abfd, sym, (bfd_vma) 0, archive_bfd);
1021+ print_symbol (abfd, sym, (bfd_vma) 0, archive_bfd, from >= fromsynth);
9951022 }
9961023 }
9971024
@@ -1001,6 +1028,7 @@ static void
10011028 display_rel_file (bfd *abfd, bfd *archive_bfd)
10021029 {
10031030 long symcount;
1031+ long synth_count = 0;
10041032 void *minisyms;
10051033 unsigned int size;
10061034 struct size_sym *symsizes;
@@ -1031,11 +1059,10 @@ display_rel_file (bfd *abfd, bfd *archive_bfd)
10311059 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
10321060 return;
10331061 }
1034-
1062+
10351063 if (show_synthetic && size == sizeof (asymbol *))
10361064 {
10371065 asymbol *synthsyms;
1038- long synth_count;
10391066 asymbol **static_syms = NULL;
10401067 asymbol **dyn_syms = NULL;
10411068 long static_count = 0;
@@ -1061,6 +1088,7 @@ display_rel_file (bfd *abfd, bfd *archive_bfd)
10611088 bfd_fatal (bfd_get_filename (abfd));
10621089 }
10631090 }
1091+
10641092 synth_count = bfd_get_synthetic_symtab (abfd, static_count, static_syms,
10651093 dyn_count, dyn_syms, &synthsyms);
10661094 if (synth_count > 0)
@@ -1106,9 +1134,9 @@ display_rel_file (bfd *abfd, bfd *archive_bfd)
11061134 }
11071135
11081136 if (! sort_by_size)
1109- print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd);
1137+ print_symbols (abfd, dynamic, minisyms, symcount, synth_count, size, archive_bfd);
11101138 else
1111- print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd);
1139+ print_size_symbols (abfd, dynamic, symsizes, symcount, synth_count, archive_bfd);
11121140
11131141 free (minisyms);
11141142 free (symsizes);
@@ -1181,6 +1209,8 @@ display_archive (bfd *file)
11811209 bfd_close (last_arfile);
11821210 lineno_cache_bfd = NULL;
11831211 lineno_cache_rel_bfd = NULL;
1212+ if (arfile == last_arfile)
1213+ return;
11841214 }
11851215 last_arfile = arfile;
11861216 }
@@ -1434,7 +1464,6 @@ print_symbol_info_bsd (struct extended_symbol_info *info, bfd *abfd)
14341464 print_value (abfd, SYM_SIZE (info));
14351465 else
14361466 print_value (abfd, SYM_VALUE (info));
1437-
14381467 if (print_size && SYM_SIZE (info))
14391468 {
14401469 printf (" ");
--- a/binutils/size.c
+++ b/binutils/size.c
@@ -365,7 +365,14 @@ display_archive (bfd *file)
365365 display_bfd (arfile);
366366
367367 if (last_arfile != NULL)
368- bfd_close (last_arfile);
368+ {
369+ bfd_close (last_arfile);
370+
371+ /* PR 17512: file: a244edbc. */
372+ if (last_arfile == arfile)
373+ return;
374+ }
375+
369376 last_arfile = arfile;
370377 }
371378