Fix potential infinite loop in bfd_cache_close_all.
authorNick Clifton <nickc@redhat.com>
Fri, 4 Aug 2023 13:19:28 +0000 (14:19 +0100)
committerNick Clifton <nickc@redhat.com>
Fri, 4 Aug 2023 13:19:28 +0000 (14:19 +0100)
  PR 15545 * cache.c (bfd_cache_close_all): Extend description to note that all files will be closed, even those that are not cacheable. Add code to prevent a possible infinite loop.

bfd/ChangeLog
bfd/cache.c

index 0087aed06a0ecef9f3323a75f55f696c1aa60874..14042207ca5c86a50e0d31166f8b09db398b491d 100644 (file)
@@ -1,3 +1,10 @@
+2023-08-04  Nick Clifton  <nickc@redhat.com>
+
+       PR 15545
+       * cache.c (bfd_cache_close_all): Extend description to note that
+       all files will be closed, even those that are not cacheable.
+       Add code to prevent a possible infinite loop.
+
 2023-08-02  Tom Tromey  <tromey@adacore.com>
 
        * pei-x86_64.c (PEI_HEADERS): Do not define.
index 0c6a948b6d6360553e6dcc63607735e54bd7ae65..357a38da5998eee7a68109e013158c21ac34b773 100644 (file)
@@ -546,7 +546,9 @@ SYNOPSIS
 
 DESCRIPTION
        Remove all BFDs from the cache. If the attached file is open,
-       then close it too.
+       then close it too.  Note - despite its name this function will
+       close a BFD even if it is not marked as being cacheable, ie
+       even if bfd_get_cacheable() returns false.
 
        <<FALSE>> is returned if closing one of the file fails, <<TRUE>> is
        returned if all is well.
@@ -558,7 +560,16 @@ bfd_cache_close_all (void)
   bool ret = true;
 
   while (bfd_last_cache != NULL)
-    ret &= bfd_cache_close (bfd_last_cache);
+    {
+      bfd *prev_bfd_last_cache = bfd_last_cache;
+
+      ret &= bfd_cache_close (bfd_last_cache);
+
+      /* Stop a potential infinite loop should bfd_cache_close()
+        not update bfd_last_cache.  */
+      if (bfd_last_cache == prev_bfd_last_cache)
+       break;
+    }
 
   return ret;
 }