From: Alan Modra Date: Sat, 19 Apr 2025 05:12:23 +0000 (+0930) Subject: bfd_check_format_matches error paths X-Git-Tag: binutils-2_45~859 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7dc5df8e5d374fa6fec2f2a6b7d1bbc258095d47;p=thirdparty%2Fbinutils-gdb.git bfd_check_format_matches error paths 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. --- diff --git a/bfd/format.c b/bfd/format.c index 3db0792d412..a909b70fe81 100644 --- a/bfd/format.c +++ b/bfd/format.c @@ -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);