This is the mail archive of the
binutils-cvs@sourceware.org
mailing list for the binutils project.
[binutils-gdb] PR22306, Invalid free() in slurp_symtab()
- From: Alan Modra <amodra at sourceware dot org>
- To: bfd-cvs at sourceware dot org
- Date: 17 Oct 2017 06:20:24 -0000
- Subject: [binutils-gdb] PR22306, Invalid free() in slurp_symtab()
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0301ce1486b1450f219202677f30d0fa97335419
commit 0301ce1486b1450f219202677f30d0fa97335419
Author: Alan Modra <amodra@gmail.com>
Date: Tue Oct 17 16:43:47 2017 +1030
PR22306, Invalid free() in slurp_symtab()
PR 22306
* aoutx.h (aout_get_external_symbols): Handle stringsize of zero,
and error for any other size that doesn't cover the header word.
Diff:
---
bfd/ChangeLog | 6 ++++++
bfd/aoutx.h | 45 ++++++++++++++++++++++++++++++---------------
2 files changed, 36 insertions(+), 15 deletions(-)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 364a36d..6f2c2b7 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2017-10-17 Alan Modra <amodra@gmail.com>
+
+ PR 22306
+ * aoutx.h (aout_get_external_symbols): Handle stringsize of zero,
+ and error for any other size that doesn't cover the header word.
+
2017-10-16 H.J. Lu <hongjiu.lu@intel.com>
* elf-bfd.h (elf_backend_data): Remove gc_sweep_hook.
diff --git a/bfd/aoutx.h b/bfd/aoutx.h
index 3d38fda..d096ed5 100644
--- a/bfd/aoutx.h
+++ b/bfd/aoutx.h
@@ -1351,27 +1351,42 @@ aout_get_external_symbols (bfd *abfd)
|| bfd_bread ((void *) string_chars, amt, abfd) != amt)
return FALSE;
stringsize = GET_WORD (abfd, string_chars);
+ if (stringsize == 0)
+ stringsize = 1;
+ else if (stringsize < BYTES_IN_WORD
+ || (size_t) stringsize != stringsize)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
#ifdef USE_MMAP
- if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
- &obj_aout_string_window (abfd), TRUE))
- return FALSE;
- strings = (char *) obj_aout_string_window (abfd).data;
-#else
- strings = (char *) bfd_malloc (stringsize + 1);
- if (strings == NULL)
- return FALSE;
-
- /* Skip space for the string count in the buffer for convenience
- when using indexes. */
- amt = stringsize - BYTES_IN_WORD;
- if (bfd_bread (strings + BYTES_IN_WORD, amt, abfd) != amt)
+ if (stringsize >= BYTES_IN_WORD)
{
- free (strings);
- return FALSE;
+ if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
+ &obj_aout_string_window (abfd), TRUE))
+ return FALSE;
+ strings = (char *) obj_aout_string_window (abfd).data;
}
+ else
#endif
+ {
+ strings = (char *) bfd_malloc (stringsize);
+ if (strings == NULL)
+ return FALSE;
+ if (stringsize >= BYTES_IN_WORD)
+ {
+ /* Keep the string count in the buffer for convenience
+ when indexing with e_strx. */
+ amt = stringsize - BYTES_IN_WORD;
+ if (bfd_bread (strings + BYTES_IN_WORD, amt, abfd) != amt)
+ {
+ free (strings);
+ return FALSE;
+ }
+ }
+ }
/* Ensure that a zero index yields an empty string. */
strings[0] = '\0';