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.

	* archive.c (_bfd_get_elt_at_filepos): Prevent an infinite loop
	accessing a corrupt nested archive.
This commit is contained in:
Nick Clifton
2013-02-15 14:37:39 +00:00
parent 76d8cf45bb
commit a043396b72
7 changed files with 92 additions and 23 deletions

View File

@ -1,6 +1,5 @@
/* 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>
@ -690,12 +689,20 @@ make_qualified_name (struct archive_info * arch,
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)
@ -704,9 +711,16 @@ make_qualified_name (struct archive_info * arch,
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