]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
bfd_check_format_matches error paths
authorAlan Modra <amodra@gmail.com>
Sat, 19 Apr 2025 05:12:23 +0000 (14:42 +0930)
committerAlan Modra <amodra@gmail.com>
Sun, 20 Apr 2025 23:32:28 +0000 (09:02 +0930)
Tidy early out errors which didn't free matching_vector.  Don't
bfd_preserve_restore if we get to err_ret from the first
bfd_preserve_save, which might fail from a memory allocation leaving
preserve.marker NULL.  Also take bfd_lock a little earlier before
modifying abfd->format to simplify error return path from a lock
failure.

bfd/format.c

index 3db0792d412e48e490d724255310a877de735ec5..a909b70fe8129e4de19dc2c06f810691779e3bca 100644 (file)
@@ -470,7 +470,18 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
   /* Avoid clashes with bfd_cache_close_all running in another
      thread.  */
   if (!bfd_cache_set_uncloseable (abfd, true, &old_in_format_matches))
-    return false;
+    {
+      free (matching_vector);
+      return false;
+    }
+
+  /* Locking is required here in order to manage _bfd_section_id.  */
+  if (!bfd_lock ())
+    {
+      bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL);
+      free (matching_vector);
+      return false;
+    }
 
   /* Presume the answer is yes.  */
   abfd->format = format;
@@ -480,10 +491,6 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
      of an archive.  */
   orig_messages = _bfd_set_error_handler_caching (&messages);
 
-  /* Locking is required here in order to manage _bfd_section_id.  */
-  if (!bfd_lock ())
-    return false;
-
   preserve_match.marker = NULL;
   if (!bfd_preserve_save (abfd, &preserve, NULL))
     goto err_ret;
@@ -779,7 +786,8 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
  out:
   if (preserve_match.marker != NULL)
     bfd_preserve_finish (abfd, &preserve_match);
-  bfd_preserve_restore (abfd, &preserve);
+  if (preserve.marker != NULL)
+    bfd_preserve_restore (abfd, &preserve);
   _bfd_restore_error_handler_caching (orig_messages);
   print_and_clear_messages (&messages, PER_XVEC_NO_TARGET);
   bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL);