+2013-02-15 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/15140
+ * archive.c (_bfd_get_elt_at_filepos): Prevent an infinite loop
+ accessing a corrupt nested archive.
+
2013-02-13 Richard Sandiford <rdsandiford@googlemail.com>
* elfxx-mips.c (mips_got_page_ref): New structure.
/* 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, 2011,
- 2012 Free Software Foundation, Inc.
+ Copyright 1990-2013 Free Software Foundation, Inc.
Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault.
This file is part of BFD, the Binary File Descriptor library.
bfd *
_bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
{
+ static file_ptr prev_filepos;
struct areltdata *new_areldata;
bfd *n_nfd;
char *filename;
n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos);
if (n_nfd)
return n_nfd;
+ /* PR15140: Prevent an inifnite recursion scanning a malformed nested archive. */
+ if (filepos == prev_filepos)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
+ }
if (0 > bfd_seek (archive, filepos, SEEK_SET))
return NULL;
return NULL;
filename = new_areldata->filename;
+ prev_filepos = filepos;
if (bfd_is_thin_archive (archive))
{
* objcopy.c (copy_main): Initialize context variable.
+2013-02-15 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/15140
+ * ar.c (open_inarch): Fail on attempts to convert a normal archive
+ to a thin archive or vice versa.
+ * elfcomm.c (make_qualified_name): Handle corrupted thin
+ archives.
+ * readelf.c (process_archive): Likewise.
+ * doc/binutils.texi: Clarify documentation describing thin
+ archives.
+
2013-02-15 Nick Clifton <nickc@redhat.com>
PR binutils/15033
/* ar.c - Archive modify and extract.
- Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
- Free Software Foundation, Inc.
+ Copyright 1991-2013 Free Software Foundation, Inc.
This file is part of GNU Binutils.
xexit (1);
}
+ if ((operation == replace || operation == quick_append)
+ && bfd_openr_next_archived_file (arch, NULL) != NULL)
+ {
+ /* PR 15140: Catch attempts to convert a normal
+ archive into a thin archive or vice versa. */
+ if (make_thin_archive && ! bfd_is_thin_archive (arch))
+ {
+ fatal (_("Cannot convert existing library %s to thin format"),
+ bfd_get_filename (arch));
+ goto bloser;
+ }
+ else if (! make_thin_archive && bfd_is_thin_archive (arch))
+ {
+ fatal (_("Cannot convert existing thin library %s to normal format"),
+ bfd_get_filename (arch));
+ goto bloser;
+ }
+ }
+
last_one = &(arch->archive_next);
/* Read all the contents right away, regardless. */
for (next_one = bfd_openr_next_archived_file (arch, NULL);
@copying
@c man begin COPYRIGHT
-Copyright @copyright{} 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-2010, 2011, 2012, 2013
-Free Software Foundation, Inc.
+Copyright @copyright{} 1991-2013 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
@cindex thin archives
@sc{gnu} @command{ar} can optionally create a @emph{thin} archive,
which contains a symbol index and references to the original copies
-of the member files of the archives. Such an archive is useful
-for building libraries for use within a local build, where the
-relocatable objects are expected to remain available, and copying the
-contents of each object would only waste time and space. Thin archives
-are also @emph{flattened}, so that adding one or more archives to a
-thin archive will add the elements of the nested archive individually.
+of the member files of the archive. This is useful for building
+libraries for use within a local build tree, where the relocatable
+objects are expected to remain available, and copying the contents of
+each object would only waste time and space.
+
+An archive can either be @emph{thin} or it can be normal. It cannot
+be both at the same time. Once an archive is created its format
+cannot be changed without first deleting it and then creating a new
+archive in its place.
+
+Thin archives are also @emph{flattened}, so that adding one thin
+archive to another thin archive does not nest it, as would happen with
+a normal archive. Instead the elements of the first archive are added
+individually to the second archive.
+
The paths to the elements of the archive are stored relative to the
archive itself.
/* elfcomm.c -- common code for ELF format file.
- Copyright 2010
- Free Software Foundation, Inc.
+ Copyright 2010-2013 Free Software Foundation, Inc.
Originally developed by Eric Youngdale <eric@andante.jic.com>
Modifications by Nick Clifton <nickc@redhat.com>
struct archive_info * nested_arch,
const char *member_name)
{
+ const char * error_name = _("<corrupt>");
size_t len;
char * name;
len = strlen (arch->file_name) + strlen (member_name) + 3;
- if (arch->is_thin_archive && arch->nested_member_origin != 0)
- len += strlen (nested_arch->file_name) + 2;
+ if (arch->is_thin_archive
+ && arch->nested_member_origin != 0)
+ {
+ /* PR 15140: Allow for corrupt thin archives. */
+ if (nested_arch->file_name)
+ len += strlen (nested_arch->file_name) + 2;
+ else
+ len += strlen (error_name) + 2;
+ }
name = (char *) malloc (len);
if (name == NULL)
return NULL;
}
- if (arch->is_thin_archive && arch->nested_member_origin != 0)
- snprintf (name, len, "%s[%s(%s)]", arch->file_name,
- nested_arch->file_name, member_name);
+ if (arch->is_thin_archive
+ && arch->nested_member_origin != 0)
+ {
+ if (nested_arch->file_name)
+ snprintf (name, len, "%s[%s(%s)]", arch->file_name,
+ nested_arch->file_name, member_name);
+ else
+ snprintf (name, len, "%s[%s(%s)]", arch->file_name,
+ error_name, member_name);
+ }
else if (arch->is_thin_archive)
snprintf (name, len, "%s[%s]", arch->file_name, member_name);
else
}
else if (is_thin_archive)
{
+ /* PR 15140: Allow for corrupt thin archives. */
+ if (nested_arch.file == NULL)
+ {
+ error (_("%s: contains corrupt thin archive: %s\n"),
+ file_name, name);
+ ret = 1;
+ break;
+ }
+
/* This is a proxy for a member of a nested archive. */
archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;