From: Alan Modra Date: Mon, 28 Feb 2011 07:46:37 +0000 (+0000) Subject: PR 12513 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8616ad89d67eac454d22da5a0bc8e5f3180779c4;p=binutils-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 91876919082..53bf1cf13e2 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2011-02-28 Alan Modra + + 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-25 Rafael Ávila de Espíndola * plugin.c (bfd_plugin_object_p): Correctly set the filesize 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;