From: Alan Modra Date: Mon, 28 Feb 2011 07:47:04 +0000 (+0000) Subject: PR 12513 X-Git-Tag: binutils-2_21_1~175 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dc39dd6264cbf965d45fa69747f33ee78dd3fb6e;p=thirdparty%2Fbinutils-gdb.git PR 12513 * archive.c (bfd_slurp_bsd_armap_f2): Sanity check parsed_size and stringsize. Properly sanity check symdef_count. Remove redundant bfd_release. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4cd05644f3c..6fd48352fd8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,18 +1,9 @@ -2011-02-15 Alan Modra +2011-02-28 Alan Modra - * elf64-ppc.c (ppc64_elf_edit_toc): Reinstate second read of - toc relocs. Fuss over free(NULL). - -2011-02-09 Alan Modra - - * 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 - - * 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 diff --git a/bfd/archive.c b/bfd/archive.c index 258c8d9aaed..c3aaffc59f5 100644 --- a/bfd/archive.c +++ b/bfd/archive.c @@ -1,6 +1,6 @@ /* 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. @@ -1109,6 +1109,7 @@ bfd_slurp_bsd_armap_f2 (bfd *abfd) 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); @@ -1136,43 +1137,46 @@ bfd_slurp_bsd_armap_f2 (bfd *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;