readelf leak in process_archive
authorAlan Modra <amodra@gmail.com>
Wed, 18 Mar 2020 23:40:32 +0000 (10:10 +1030)
committerAlan Modra <amodra@gmail.com>
Thu, 19 Mar 2020 01:52:32 +0000 (12:22 +1030)
* readelf.c (process_archive): Always return via path freeing
memory.  Formatting.

binutils/ChangeLog
binutils/readelf.c

index 7522653315d7ca96d81570fcb6efdbf39b2f97c6..e52a14f836069d32a35020d933e833b7e990ace1 100644 (file)
@@ -1,3 +1,8 @@
+2020-03-19  Alan Modra  <amodra@gmail.com>
+
+       * readelf.c (process_archive): Always return via path freeing
+       memory.  Formatting.
+
 2020-03-19  Alan Modra  <amodra@gmail.com>
 
        * readelf.c (process_netbsd_elf_note): Validate descsz before
index c8ca66e52cf203d9ad1005683c5a4092e810c069..f76b9f6d8e6baa98d5888893c18e912093af4b8c 100644 (file)
@@ -20256,49 +20256,58 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
   if (do_archive_index)
     {
       if (arch.sym_table == NULL)
-       error (_("%s: unable to dump the index as none was found\n"), filedata->file_name);
+       error (_("%s: unable to dump the index as none was found\n"),
+              filedata->file_name);
       else
        {
          unsigned long i, l;
          unsigned long current_pos;
 
-         printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
-                 filedata->file_name, (unsigned long) arch.index_num, arch.sym_size);
+         printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
+                   "in the symbol table)\n"),
+                 filedata->file_name, (unsigned long) arch.index_num,
+                 arch.sym_size);
 
          current_pos = ftell (filedata->handle);
 
          for (i = l = 0; i < arch.index_num; i++)
            {
-             if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
-               {
-                 char * member_name;
-
-                 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
+             if (i == 0
+                 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
+               {
+                 char * member_name
+                   = get_archive_member_name_at (&arch, arch.index_array[i],
+                                                 &nested_arch);
 
-                  if (member_name != NULL)
-                    {
-                     char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
+                 if (member_name != NULL)
+                   {
+                     char * qualified_name
+                       = make_qualified_name (&arch, &nested_arch,
+                                              member_name);
 
-                      if (qualified_name != NULL)
-                        {
-                         printf (_("Contents of binary %s at offset "), qualified_name);
+                     if (qualified_name != NULL)
+                       {
+                         printf (_("Contents of binary %s at offset "),
+                                 qualified_name);
                          (void) print_vma (arch.index_array[i], PREFIX_HEX);
                          putchar ('\n');
-                         free (qualified_name);
-                       }
+                         free (qualified_name);
+                       }
                      free (member_name);
                    }
                }
 
              if (l >= arch.sym_size)
                {
-                 error (_("%s: end of the symbol table reached before the end of the index\n"),
+                 error (_("%s: end of the symbol table reached "
+                          "before the end of the index\n"),
                         filedata->file_name);
                  ret = FALSE;
                  break;
                }
              /* PR 17531: file: 0b6630b2.  */
-             printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
+             printf ("\t%.*s\n",
+                     (int) (arch.sym_size - l), arch.sym_table + l);
              l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
            }
 
@@ -20322,7 +20331,8 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
 
          if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
            {
-             error (_("%s: failed to seek back to start of object files in the archive\n"),
+             error (_("%s: failed to seek back to start of object files "
+                      "in the archive\n"),
                     filedata->file_name);
              ret = FALSE;
              goto out;
@@ -20347,34 +20357,37 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
 
       /* Read the next archive header.  */
       if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
-        {
-          error (_("%s: failed to seek to next archive header\n"), arch.file_name);
-          return FALSE;
-        }
+       {
+         error (_("%s: failed to seek to next archive header\n"),
+                arch.file_name);
+         ret = FALSE;
+         break;
+       }
       got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
       if (got != sizeof arch.arhdr)
-        {
-          if (got == 0)
+       {
+         if (got == 0)
            break;
          /* PR 24049 - we cannot use filedata->file_name as this will
             have already been freed.  */
          error (_("%s: failed to read archive header\n"), arch.file_name);
 
-          ret = FALSE;
-          break;
-        }
+         ret = FALSE;
+         break;
+       }
       if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
-        {
-          error (_("%s: did not find a valid archive header\n"), arch.file_name);
-          ret = FALSE;
-          break;
-        }
+       {
+         error (_("%s: did not find a valid archive header\n"),
+                arch.file_name);
+         ret = FALSE;
+         break;
+       }
 
       arch.next_arhdr_offset += sizeof arch.arhdr;
 
       archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
       if (archive_file_size & 01)
-        ++archive_file_size;
+       ++archive_file_size;
 
       name = get_archive_member_name (&arch, &nested_arch);
       if (name == NULL)
@@ -20395,45 +20408,45 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
        }
 
       if (is_thin_archive && arch.nested_member_origin == 0)
-        {
-          /* This is a proxy for an external member of a thin archive.  */
-          Filedata * member_filedata;
-          char * member_file_name = adjust_relative_path
+       {
+         /* This is a proxy for an external member of a thin archive.  */
+         Filedata * member_filedata;
+         char * member_file_name = adjust_relative_path
            (filedata->file_name, name, namelen);
 
          free (name);
-          if (member_file_name == NULL)
-            {
+         if (member_file_name == NULL)
+           {
              free (qualified_name);
-              ret = FALSE;
-              break;
-            }
+             ret = FALSE;
+             break;
+           }
 
-          member_filedata = open_file (member_file_name);
-          if (member_filedata == NULL)
-            {
-              error (_("Input file '%s' is not readable.\n"), member_file_name);
-              free (member_file_name);
+         member_filedata = open_file (member_file_name);
+         if (member_filedata == NULL)
+           {
+             error (_("Input file '%s' is not readable.\n"), member_file_name);
+             free (member_file_name);
              free (qualified_name);
-              ret = FALSE;
-              break;
-            }
+             ret = FALSE;
+             break;
+           }
 
-          archive_file_offset = arch.nested_member_origin;
+         archive_file_offset = arch.nested_member_origin;
          member_filedata->file_name = qualified_name;
 
-          if (! process_object (member_filedata))
+         if (! process_object (member_filedata))
            ret = FALSE;
 
-          close_file (member_filedata);
-          free (member_file_name);
+         close_file (member_filedata);
+         free (member_file_name);
          free (qualified_name);
-        }
+       }
       else if (is_thin_archive)
-        {
-          Filedata thin_filedata;
+       {
+         Filedata thin_filedata;
 
-          memset (&thin_filedata, 0, sizeof (thin_filedata));
+         memset (&thin_filedata, 0, sizeof (thin_filedata));
 
          /* PR 15140: Allow for corrupt thin archives.  */
          if (nested_arch.file == NULL)
@@ -20447,35 +20460,36 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
            }
          free (name);
 
-          /* This is a proxy for a member of a nested archive.  */
-          archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
+         /* This is a proxy for a member of a nested archive.  */
+         archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
 
-          /* The nested archive file will have been opened and setup by
-             get_archive_member_name.  */
-          if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
-            {
-              error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
+         /* The nested archive file will have been opened and setup by
+            get_archive_member_name.  */
+         if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
+           {
+             error (_("%s: failed to seek to archive member.\n"),
+                    nested_arch.file_name);
              free (qualified_name);
-              ret = FALSE;
-              break;
-            }
+             ret = FALSE;
+             break;
+           }
 
          thin_filedata.handle = nested_arch.file;
          thin_filedata.file_name = qualified_name;
 
-          if (! process_object (& thin_filedata))
+         if (! process_object (& thin_filedata))
            ret = FALSE;
-        }
+       }
       else
-        {
+       {
          free (name);
-          archive_file_offset = arch.next_arhdr_offset;
-          arch.next_arhdr_offset += archive_file_size;
+         archive_file_offset = arch.next_arhdr_offset;
+         arch.next_arhdr_offset += archive_file_size;
 
          filedata->file_name = qualified_name;
-          if (! process_object (filedata))
+         if (! process_object (filedata))
            ret = FALSE;
-        }
+       }
 
       free (qualified_name);
     }