about summary refs log tree commit diff
path: root/support/temp_file.c
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2017-05-08 14:57:59 +0200
committerFlorian Weimer <fweimer@redhat.com>2017-05-08 16:20:40 +0200
commitc22553effb151532eb95fc1f7bb17a3aebe63202 (patch)
tree6064f0d1bf34b0ec8aaebd04cd1758c81f4666ce /support/temp_file.c
parent706256afb6c844a0e6aaab2b60f4326b91aca2e9 (diff)
downloadglibc-c22553effb151532eb95fc1f7bb17a3aebe63202.tar.gz
glibc-c22553effb151532eb95fc1f7bb17a3aebe63202.tar.xz
glibc-c22553effb151532eb95fc1f7bb17a3aebe63202.zip
support: Prevent multiple deletion of temporary files
Otherwise, another user might recreate these files after the first
deletion.  Particularly with temporary directories, this could result
in the removal of unintended files through symbol link attacks.
Diffstat (limited to 'support/temp_file.c')
-rw-r--r--support/temp_file.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/support/temp_file.c b/support/temp_file.c
index 50cbae606b..fdb2477ab9 100644
--- a/support/temp_file.c
+++ b/support/temp_file.c
@@ -28,12 +28,14 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 /* List of temporary files.  */
 static struct temp_name_list
 {
   struct temp_name_list *next;
   char *name;
+  pid_t owner;
 } *temp_name_list;
 
 /* Location of the temporary files.  Set by the test skeleton via
@@ -50,6 +52,7 @@ add_temp_file (const char *name)
     {
       newp->name = newname;
       newp->next = temp_name_list;
+      newp->owner = getpid ();
       temp_name_list = newp;
     }
   else
@@ -94,12 +97,19 @@ support_set_test_dir (const char *path)
 void
 support_delete_temp_files (void)
 {
+  pid_t pid = getpid ();
   while (temp_name_list != NULL)
     {
-      /* For some tests, the temporary file removal runs multiple
-	 times (in the parent processes and the subprocess), so do not
-	 report a failed removal attempt.  */
-      (void) remove (temp_name_list->name);
+      /* Only perform the removal if the path was registed in the same
+	 process, as identified by the PID.  (This assumes that the
+	 parent process which registered the temporary file sticks
+	 around, to prevent PID reuse.)  */
+      if (temp_name_list->owner == pid)
+	{
+	  if (remove (temp_name_list->name) != 0)
+	    printf ("warning: could not remove temporary file: %s: %m\n",
+		    temp_name_list->name);
+	}
       free (temp_name_list->name);
 
       struct temp_name_list *next = temp_name_list->next;