aboutsummaryrefslogtreecommitdiff
path: root/bfd/archive.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2011-02-28 07:46:37 +0000
committerAlan Modra <amodra@gmail.com>2011-02-28 07:46:37 +0000
commit8616ad89d67eac454d22da5a0bc8e5f3180779c4 (patch)
tree25154921607756942bc7f44dcacf4760d1b96db8 /bfd/archive.c
parent5a0ade8b7098e7d6a63946835b053b4cca92912e (diff)
downloadgdb-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.c32
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;