aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-03-14 11:50:22 +1030
committerAlan Modra <amodra@gmail.com>2020-03-14 17:24:19 +1030
commit780f96aed2b4db1014e8fa2b50118676d8af0e46 (patch)
tree06cceab0c41b0978c51811e1c280733045ee1488 /binutils
parentf761cb13a903da6a5a1b3f9a5cb984600124ac31 (diff)
downloadgdb-780f96aed2b4db1014e8fa2b50118676d8af0e46.zip
gdb-780f96aed2b4db1014e8fa2b50118676d8af0e46.tar.gz
gdb-780f96aed2b4db1014e8fa2b50118676d8af0e46.tar.bz2
readelf large memory allocation
* elfcomm.h (setup_archive): Update prototype. * elfcomm.c (setup_archive): Add file_size parameter and sanity check longnames_size. (setup_nested_archive): Get file size and pass to setup_archive. * elfedit.c (process_archive): Likewise. * readelf.c (process_archive): Pass filedata->file_size to setup_archive.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog10
-rw-r--r--binutils/elfcomm.c12
-rw-r--r--binutils/elfcomm.h2
-rw-r--r--binutils/elfedit.c5
-rw-r--r--binutils/readelf.c3
5 files changed, 25 insertions, 7 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 9a64b0d..5101b8c 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,15 @@
2020-03-14 Alan Modra <amodra@gmail.com>
+ * elfcomm.h (setup_archive): Update prototype.
+ * elfcomm.c (setup_archive): Add file_size parameter and sanity
+ check longnames_size.
+ (setup_nested_archive): Get file size and pass to setup_archive.
+ * elfedit.c (process_archive): Likewise.
+ * readelf.c (process_archive): Pass filedata->file_size to
+ setup_archive.
+
+2020-03-14 Alan Modra <amodra@gmail.com>
+
* readelf.c (dump_section_as_strings): Free memory on error exit.
(dump_section_as_bytes, process_notes_at): Likewise.
(get_build_id): Free enote.
diff --git a/binutils/elfcomm.c b/binutils/elfcomm.c
index 3060ff1..e5c6a32 100644
--- a/binutils/elfcomm.c
+++ b/binutils/elfcomm.c
@@ -607,8 +607,8 @@ process_archive_index_and_symbols (struct archive_info * arch,
int
setup_archive (struct archive_info *arch, const char *file_name,
- FILE *file, bfd_boolean is_thin_archive,
- bfd_boolean read_symbols)
+ FILE *file, bfd_size_type file_size,
+ bfd_boolean is_thin_archive, bfd_boolean read_symbols)
{
size_t got;
@@ -671,7 +671,8 @@ setup_archive (struct archive_info *arch, const char *file_name,
return 1;
}
/* PR 17531: file: 639d6a26. */
- if ((signed long) arch->longnames_size < 0)
+ if (arch->longnames_size > file_size
+ || (signed long) arch->longnames_size < 0)
{
error (_("%s: long name table is too big, (size = 0x%lx)\n"),
file_name, arch->longnames_size);
@@ -713,6 +714,7 @@ setup_nested_archive (struct archive_info *nested_arch,
const char *member_file_name)
{
FILE * member_file;
+ struct stat statbuf;
/* Have we already setup this archive? */
if (nested_arch->file_name != NULL
@@ -727,8 +729,10 @@ setup_nested_archive (struct archive_info *nested_arch,
member_file = fopen (member_file_name, "rb");
if (member_file == NULL)
return 1;
+ if (fstat (fileno (member_file), &statbuf) < 0)
+ return 1;
return setup_archive (nested_arch, member_file_name, member_file,
- FALSE, FALSE);
+ statbuf.st_size, FALSE, FALSE);
}
/* Release the memory used for the archive information. */
diff --git a/binutils/elfcomm.h b/binutils/elfcomm.h
index 9bf3c41..731d3db 100644
--- a/binutils/elfcomm.h
+++ b/binutils/elfcomm.h
@@ -74,7 +74,7 @@ extern char *adjust_relative_path (const char *, const char *, unsigned long);
/* Read the symbol table and long-name table from an archive. */
extern int setup_archive (struct archive_info *, const char *, FILE *,
- bfd_boolean, bfd_boolean);
+ bfd_size_type, bfd_boolean, bfd_boolean);
/* Open and setup a nested archive, if not already open. */
extern int setup_nested_archive (struct archive_info *, const char *);
diff --git a/binutils/elfedit.c b/binutils/elfedit.c
index 3a14c60..d0e4e95 100644
--- a/binutils/elfedit.c
+++ b/binutils/elfedit.c
@@ -541,6 +541,7 @@ process_archive (const char * file_name, FILE * file,
struct archive_info nested_arch;
size_t got;
int ret;
+ struct stat statbuf;
/* The ARCH structure is used to hold information about this archive. */
arch.file_name = NULL;
@@ -558,7 +559,9 @@ process_archive (const char * file_name, FILE * file,
nested_arch.sym_table = NULL;
nested_arch.longnames = NULL;
- if (setup_archive (&arch, file_name, file, is_thin_archive, FALSE) != 0)
+ if (fstat (fileno (file), &statbuf) < 0
+ || setup_archive (&arch, file_name, file, statbuf.st_size,
+ is_thin_archive, FALSE) != 0)
{
ret = 1;
goto out;
diff --git a/binutils/readelf.c b/binutils/readelf.c
index b106e8c..0f8a080 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -20247,7 +20247,8 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
nested_arch.longnames = NULL;
if (setup_archive (&arch, filedata->file_name, filedata->handle,
- is_thin_archive, do_archive_index) != 0)
+ filedata->file_size, is_thin_archive,
+ do_archive_index) != 0)
{
ret = FALSE;
goto out;