Blame elfutils-0.189-debuginfod_config_cache-double-close.patch

Mark Wielaard b3a7c8
diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
Mark Wielaard b3a7c8
index ef4d47e3..d92d8d62 100644
Mark Wielaard b3a7c8
--- a/debuginfod/debuginfod-client.c
Mark Wielaard b3a7c8
+++ b/debuginfod/debuginfod-client.c
Mark Wielaard b3a7c8
@@ -248,7 +248,7 @@ debuginfod_write_callback (char *ptr, size_t size, size_t nmemb, void *data)
Mark Wielaard b3a7c8
 
Mark Wielaard b3a7c8
 /* handle config file read and write */
Mark Wielaard b3a7c8
 static int
Mark Wielaard b3a7c8
-debuginfod_config_cache(char *config_path,
Mark Wielaard b3a7c8
+debuginfod_config_cache(debuginfod_client *c, char *config_path,
Mark Wielaard b3a7c8
 			long cache_config_default_s,
Mark Wielaard b3a7c8
 			struct stat *st)
Mark Wielaard b3a7c8
 {
Mark Wielaard b3a7c8
@@ -277,17 +277,27 @@ debuginfod_config_cache(char *config_path,
Mark Wielaard b3a7c8
     }
Mark Wielaard b3a7c8
 
Mark Wielaard b3a7c8
   long cache_config;
Mark Wielaard b3a7c8
+  /* PR29696 - NB: When using fdopen, the file descriptor is NOT
Mark Wielaard b3a7c8
+     dup'ed and will be closed when the stream is closed. Manually
Mark Wielaard b3a7c8
+     closing fd after fclose is called will lead to a race condition
Mark Wielaard b3a7c8
+     where, if reused, the file descriptor will compete for its
Mark Wielaard b3a7c8
+     regular use before being incorrectly closed here.  */
Mark Wielaard b3a7c8
   FILE *config_file = fdopen(fd, "r");
Mark Wielaard b3a7c8
   if (config_file)
Mark Wielaard b3a7c8
     {
Mark Wielaard b3a7c8
       if (fscanf(config_file, "%ld", &cache_config) != 1)
Mark Wielaard b3a7c8
-        cache_config = cache_config_default_s;
Mark Wielaard b3a7c8
-      fclose(config_file);
Mark Wielaard b3a7c8
+	cache_config = cache_config_default_s;
Mark Wielaard b3a7c8
+      if (0 != fclose (config_file) && c->verbose_fd >= 0)
Mark Wielaard b3a7c8
+	dprintf (c->verbose_fd, "fclose failed with %s (err=%d)\n",
Mark Wielaard b3a7c8
+		 strerror (errno), errno);
Mark Wielaard b3a7c8
     }
Mark Wielaard b3a7c8
   else
Mark Wielaard b3a7c8
-    cache_config = cache_config_default_s;
Mark Wielaard b3a7c8
-
Mark Wielaard b3a7c8
-  close (fd);
Mark Wielaard b3a7c8
+    {
Mark Wielaard b3a7c8
+      cache_config = cache_config_default_s;
Mark Wielaard b3a7c8
+      if (0 != close (fd) && c->verbose_fd >= 0)
Mark Wielaard b3a7c8
+	dprintf (c->verbose_fd, "close failed with %s (err=%d)\n",
Mark Wielaard b3a7c8
+		 strerror (errno), errno);
Mark Wielaard b3a7c8
+    }
Mark Wielaard b3a7c8
   return cache_config;
Mark Wielaard b3a7c8
 }
Mark Wielaard b3a7c8
 
Mark Wielaard b3a7c8
@@ -303,7 +313,7 @@ debuginfod_clean_cache(debuginfod_client *c,
Mark Wielaard b3a7c8
   struct stat st;
Mark Wielaard b3a7c8
 
Mark Wielaard b3a7c8
   /* Create new interval file.  */
Mark Wielaard b3a7c8
-  rc = debuginfod_config_cache(interval_path,
Mark Wielaard b3a7c8
+  rc = debuginfod_config_cache(c, interval_path,
Mark Wielaard b3a7c8
 			       cache_clean_default_interval_s, &st);
Mark Wielaard b3a7c8
   if (rc < 0)
Mark Wielaard b3a7c8
     return rc;
Mark Wielaard b3a7c8
@@ -320,7 +330,7 @@ debuginfod_clean_cache(debuginfod_client *c,
Mark Wielaard b3a7c8
   utime (interval_path, NULL);
Mark Wielaard b3a7c8
 
Mark Wielaard b3a7c8
   /* Read max unused age value from config file.  */
Mark Wielaard b3a7c8
-  rc = debuginfod_config_cache(max_unused_path,
Mark Wielaard b3a7c8
+  rc = debuginfod_config_cache(c, max_unused_path,
Mark Wielaard b3a7c8
 			       cache_default_max_unused_age_s, &st);
Mark Wielaard b3a7c8
   if (rc < 0)
Mark Wielaard b3a7c8
     return rc;
Mark Wielaard b3a7c8
@@ -1110,7 +1135,7 @@ debuginfod_query_server (debuginfod_client *c,
Mark Wielaard b3a7c8
 
Mark Wielaard b3a7c8
           close(fd); /* no need to hold onto the negative-hit file descriptor */
Mark Wielaard b3a7c8
           
Mark Wielaard b3a7c8
-          rc = debuginfod_config_cache(cache_miss_path,
Mark Wielaard b3a7c8
+          rc = debuginfod_config_cache(c, cache_miss_path,
Mark Wielaard b3a7c8
                                        cache_miss_default_s, &st);
Mark Wielaard b3a7c8
           if (rc < 0)
Mark Wielaard b3a7c8
             goto out;