Avoid concurrency problem in ldconfig (bug 23973)

Message ID mvmsgxm9gf2.fsf@suse.de
State Superseded
Headers

Commit Message

Andreas Schwab Jan. 21, 2019, 3:30 p.m. UTC
  Use a unique name for the temporary file when updating the ld.so cache, so
that two concurrent runs of ldconfig don't write to the same file.

	* elf/cache.c (save_cache): Use unique temporary name.
	(save_aux_cache): Likewise.
---
 elf/cache.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)
  

Patch

diff --git a/elf/cache.c b/elf/cache.c
index b8e9e6ccc32e..ec7d94b0bc30 100644
--- a/elf/cache.c
+++ b/elf/cache.c
@@ -427,12 +427,12 @@  save_cache (const char *cache_name)
   /* Write out the cache.  */
 
   /* Write cache first to a temporary file and rename it later.  */
-  char *temp_name = xmalloc (strlen (cache_name) + 2);
-  sprintf (temp_name, "%s~", cache_name);
+  char *temp_name;
+  if (asprintf (&temp_name, "%s.XXXXXX", cache_name) < 0)
+    error (EXIT_FAILURE, errno, _("Can't allocate temporary name for cache file"));
 
   /* Create file.  */
-  int fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW,
-		 S_IRUSR|S_IWUSR);
+  int fd = mkostemp (temp_name, O_NOFOLLOW);
   if (fd < 0)
     error (EXIT_FAILURE, errno, _("Can't create temporary cache file %s"),
 	   temp_name);
@@ -481,6 +481,7 @@  save_cache (const char *cache_name)
   free (file_entries_new);
   free (file_entries);
   free (strings);
+  free (temp_name);
 
   while (entries)
     {
@@ -804,8 +805,9 @@  save_aux_cache (const char *aux_cache_name)
   /* Write out auxiliary cache file.  */
   /* Write auxiliary cache first to a temporary file and rename it later.  */
 
-  char *temp_name = xmalloc (strlen (aux_cache_name) + 2);
-  sprintf (temp_name, "%s~", aux_cache_name);
+  char *temp_name;
+  if (asprintf (&temp_name, "%s.XXXXXX", aux_cache_name) < 0)
+    goto out_fail2;
 
   /* Check that directory exists and create if needed.  */
   char *dir = strdupa (aux_cache_name);
@@ -819,8 +821,7 @@  save_aux_cache (const char *aux_cache_name)
     }
 
   /* Create file.  */
-  int fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW,
-		 S_IRUSR|S_IWUSR);
+  int fd = mkostemp (temp_name, O_NOFOLLOW);
   if (fd < 0)
     goto out_fail;
 
@@ -840,5 +841,6 @@  save_aux_cache (const char *aux_cache_name)
 out_fail:
   /* Free allocated memory.  */
   free (temp_name);
+out_fail2:
   free (file_entries);
 }