-2011-02-15 Alan Modra <amodra@gmail.com>
+2011-02-28 Alan Modra <amodra@gmail.com>
- * elf64-ppc.c (ppc64_elf_edit_toc): Reinstate second read of
- toc relocs. Fuss over free(NULL).
-
-2011-02-09 Alan Modra <amodra@gmail.com>
-
- * elf64-ppc.c (ppc64_elf_edit_toc): Don't free toc relocs until
- we are done. When optimising large toc, check that a global
- symbol on a toc reloc is defined in a kept section.
-
-2011-02-08 Alan Modra <amodra@gmail.com>
-
- * elf64-ppc.c (ppc64_elf_edit_toc): Don't segfault on NULL
- local_syms when looking for local symbols in .toc.
+ PR 12513
+ * archive.c (bfd_slurp_bsd_armap_f2): Sanity check parsed_size and
+ stringsize. Properly sanity check symdef_count. Remove redundant
+ bfd_release.
2011-02-01 Alan Modra <amodra@gmail.com>
/* BFD back-end for archive files (libraries).
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault.
struct artdata *ardata = bfd_ardata (abfd);
char *stringbase;
unsigned int stringsize;
+ unsigned int left;
bfd_size_type amt;
carsym *set;
int i = bfd_bread (nextname, 16, abfd);
if (mapdata == NULL)
return FALSE;
- amt = mapdata->parsed_size;
- raw_armap = (bfd_byte *) bfd_zalloc (abfd, amt);
- if (raw_armap == NULL)
+ if (mapdata->parsed_size < HPUX_SYMDEF_COUNT_SIZE + BSD_STRING_COUNT_SIZE)
{
+ wrong_format:
+ bfd_set_error (bfd_error_wrong_format);
byebye:
bfd_release (abfd, mapdata);
return FALSE;
}
+ left = mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE - BSD_STRING_COUNT_SIZE;
+
+ amt = mapdata->parsed_size;
+ raw_armap = (bfd_byte *) bfd_zalloc (abfd, amt);
+ if (raw_armap == NULL)
+ goto byebye;
if (bfd_bread (raw_armap, amt, abfd) != amt)
{
if (bfd_get_error () != bfd_error_system_call)
bfd_set_error (bfd_error_malformed_archive);
- byebyebye:
- bfd_release (abfd, raw_armap);
goto byebye;
}
ardata->symdef_count = H_GET_16 (abfd, raw_armap);
- if (ardata->symdef_count * BSD_SYMDEF_SIZE
- > mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE)
- {
- /* Probably we're using the wrong byte ordering. */
- bfd_set_error (bfd_error_wrong_format);
- goto byebyebye;
- }
-
ardata->cache = 0;
stringsize = H_GET_32 (abfd, raw_armap + HPUX_SYMDEF_COUNT_SIZE);
+ if (stringsize > left)
+ goto wrong_format;
+ left -= stringsize;
+
/* Skip sym count and string sz. */
stringbase = ((char *) raw_armap
+ HPUX_SYMDEF_COUNT_SIZE
+ BSD_STRING_COUNT_SIZE);
rbase = (bfd_byte *) stringbase + stringsize;
amt = ardata->symdef_count * BSD_SYMDEF_SIZE;
+ if (amt > left)
+ goto wrong_format;
+
ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt);
if (!ardata->symdefs)
return FALSE;