closures: Create temporary file with O_TMPFILE and O_CLOEXEC when available
The open_temp_exec_file_dir function can create a temporary file without file system accessible link. If the O_TMPFILE flag is not defined (old Linux kernel or libc) the behavior is unchanged. The open_temp_exec_file_name function now need a new argument "flags" (like O_CLOEXEC) used for temporary file creation. The O_TMPFILE flag allow temporary file creation without race condition. This feature/fix prevent another process to access the (future) executable file from the file system. The O_CLOEXEC flag automatically close the temporary file for any execve. This avoid transmitting (executable) file descriptor to a child process.
This commit is contained in:
@@ -265,9 +265,9 @@ static size_t execsize = 0;
|
||||
|
||||
/* Open a temporary file name, and immediately unlink it. */
|
||||
static int
|
||||
open_temp_exec_file_name (char *name)
|
||||
open_temp_exec_file_name (char *name, int flags)
|
||||
{
|
||||
int fd = mkstemp (name);
|
||||
int fd = mkostemp (name, flags);
|
||||
|
||||
if (fd != -1)
|
||||
unlink (name);
|
||||
@@ -280,8 +280,27 @@ static int
|
||||
open_temp_exec_file_dir (const char *dir)
|
||||
{
|
||||
static const char suffix[] = "/ffiXXXXXX";
|
||||
size_t lendir = strlen (dir);
|
||||
char *tempname = __builtin_alloca (lendir + sizeof (suffix));
|
||||
int lendir, flags, fd;
|
||||
char *tempname;
|
||||
|
||||
#ifdef O_CLOEXEC
|
||||
flags = O_CLOEXEC;
|
||||
#else
|
||||
flags = 0;
|
||||
#endif
|
||||
|
||||
#ifdef O_TMPFILE
|
||||
fd = open (dir, flags | O_RDWR | O_EXCL | O_TMPFILE, 0700);
|
||||
/* If the running system does not support the O_TMPFILE flag then retry without it. */
|
||||
if (fd != -1 || (errno != EINVAL && errno != EISDIR && errno != EOPNOTSUPP)) {
|
||||
return fd;
|
||||
} else {
|
||||
errno = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
lendir = strlen (dir);
|
||||
tempname = __builtin_alloca (lendir + sizeof (suffix));
|
||||
|
||||
if (!tempname)
|
||||
return -1;
|
||||
@@ -289,7 +308,7 @@ open_temp_exec_file_dir (const char *dir)
|
||||
memcpy (tempname, dir, lendir);
|
||||
memcpy (tempname + lendir, suffix, sizeof (suffix));
|
||||
|
||||
return open_temp_exec_file_name (tempname);
|
||||
return open_temp_exec_file_name (tempname, flags);
|
||||
}
|
||||
|
||||
/* Open a temporary file in the directory in the named environment
|
||||
|
||||
Reference in New Issue
Block a user