diff options
author | Alan Modra <amodra@gmail.com> | 2011-02-28 07:46:37 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2011-02-28 07:46:37 +0000 |
commit | 8616ad89d67eac454d22da5a0bc8e5f3180779c4 (patch) | |
tree | 25154921607756942bc7f44dcacf4760d1b96db8 /bfd/archive.c | |
parent | 5a0ade8b7098e7d6a63946835b053b4cca92912e (diff) | |
download | gdb-8616ad89d67eac454d22da5a0bc8e5f3180779c4.zip gdb-8616ad89d67eac454d22da5a0bc8e5f3180779c4.tar.gz gdb-8616ad89d67eac454d22da5a0bc8e5f3180779c4.tar.bz2 |
PR 12513
* archive.c (bfd_slurp_bsd_armap_f2): Sanity check parsed_size and
stringsize. Properly sanity check symdef_count. Remove redundant
bfd_release.
Diffstat (limited to 'bfd/archive.c')
-rw-r--r-- | bfd/archive.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/bfd/archive.c b/bfd/archive.c index 258c8d9..c3aaffc 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; |