PR22306, Invalid free() in slurp_symtab()
authorAlan Modra <amodra@gmail.com>
Tue, 17 Oct 2017 06:13:47 +0000 (16:43 +1030)
committerAlan Modra <amodra@gmail.com>
Tue, 17 Oct 2017 06:17:44 +0000 (16:47 +1030)
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.

bfd/ChangeLog
bfd/aoutx.h

index 364a36d24b01fc1b44b44726bd4d684c98ae5ff6..6f2c2b71de614249675206c3d537002b44d56d23 100644 (file)
@@ -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.
index 3d38fda14bcda87303b22aaaa46992bba0d52000..d096ed5566bdfaa4b9a4f66129f02fd7c58d0ac1 100644 (file)
@@ -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';