|
|
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 |
|