Blame SOURCES/libffi-3.0.13-closures-Create-temporary-file-with-O_TMPFILE-and-O_.patch

e9b5f4
From 8daeed9570af72eb135c8ded460d2888f05b2e68 Mon Sep 17 00:00:00 2001
e9b5f4
From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= <mic@digikod.net>
e9b5f4
Date: Sun, 11 May 2014 22:54:58 +0200
e9b5f4
Subject: [PATCH 626/627] closures: Create temporary file with O_TMPFILE and
e9b5f4
 O_CLOEXEC when available
e9b5f4
e9b5f4
The open_temp_exec_file_dir function can create a temporary file without
e9b5f4
file system accessible link. If the O_TMPFILE flag is not defined (old
e9b5f4
Linux kernel or libc) the behavior is unchanged.
e9b5f4
e9b5f4
The open_temp_exec_file_name function now need a new argument "flags"
e9b5f4
(like O_CLOEXEC) used for temporary file creation.
e9b5f4
e9b5f4
The O_TMPFILE flag allow temporary file creation without race condition.
e9b5f4
This feature/fix prevent another process to access the (future)
e9b5f4
executable file from the file system.
e9b5f4
e9b5f4
The O_CLOEXEC flag automatically close the temporary file for any
e9b5f4
execve. This avoid transmitting (executable) file descriptor to a child
e9b5f4
process.
e9b5f4
---
e9b5f4
 src/closures.c | 29 ++++++++++++++++++++++++-----
e9b5f4
 1 file changed, 24 insertions(+), 5 deletions(-)
e9b5f4
e9b5f4
diff --git a/src/closures.c b/src/closures.c
e9b5f4
index c7863f3..9799ce6 100644
e9b5f4
--- a/src/closures.c
e9b5f4
+++ b/src/closures.c
e9b5f4
@@ -265,9 +265,9 @@ static size_t execsize = 0;
e9b5f4
 
e9b5f4
 /* Open a temporary file name, and immediately unlink it.  */
e9b5f4
 static int
e9b5f4
-open_temp_exec_file_name (char *name)
e9b5f4
+open_temp_exec_file_name (char *name, int flags)
e9b5f4
 {
e9b5f4
-  int fd = mkstemp (name);
e9b5f4
+  int fd = mkostemp (name, flags);
e9b5f4
 
e9b5f4
   if (fd != -1)
e9b5f4
     unlink (name);
e9b5f4
@@ -280,8 +280,27 @@ static int
e9b5f4
 open_temp_exec_file_dir (const char *dir)
e9b5f4
 {
e9b5f4
   static const char suffix[] = "/ffiXXXXXX";
e9b5f4
-  int lendir = strlen (dir);
e9b5f4
-  char *tempname = __builtin_alloca (lendir + sizeof (suffix));
e9b5f4
+  int lendir, flags, fd;
e9b5f4
+  char *tempname;
e9b5f4
+
e9b5f4
+#ifdef O_CLOEXEC
e9b5f4
+  flags = O_CLOEXEC;
e9b5f4
+#else
e9b5f4
+  flags = 0;
e9b5f4
+#endif
e9b5f4
+
e9b5f4
+#ifdef O_TMPFILE
e9b5f4
+  fd = open (dir, flags | O_RDWR | O_EXCL | O_TMPFILE, 0700);
e9b5f4
+  /* If the running system does not support the O_TMPFILE flag then retry without it. */
e9b5f4
+  if (fd != -1 || (errno != EINVAL && errno != EISDIR && errno != EOPNOTSUPP)) {
e9b5f4
+    return fd;
e9b5f4
+  } else {
e9b5f4
+    errno = 0;
e9b5f4
+  }
e9b5f4
+#endif
e9b5f4
+
e9b5f4
+  lendir = strlen (dir);
e9b5f4
+  tempname = __builtin_alloca (lendir + sizeof (suffix));
e9b5f4
 
e9b5f4
   if (!tempname)
e9b5f4
     return -1;
e9b5f4
@@ -289,7 +308,7 @@ open_temp_exec_file_dir (const char *dir)
e9b5f4
   memcpy (tempname, dir, lendir);
e9b5f4
   memcpy (tempname + lendir, suffix, sizeof (suffix));
e9b5f4
 
e9b5f4
-  return open_temp_exec_file_name (tempname);
e9b5f4
+  return open_temp_exec_file_name (tempname, flags);
e9b5f4
 }
e9b5f4
 
e9b5f4
 /* Open a temporary file in the directory in the named environment
e9b5f4
-- 
e9b5f4
1.7.12.1
e9b5f4