Skip to content

Commit

Permalink
closures: Create temporary file with O_TMPFILE and O_CLOEXEC when ava…
Browse files Browse the repository at this point in the history
…ilable

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.
  • Loading branch information
l0kod committed May 19, 2014
1 parent 0403f33 commit 8daeed9
Showing 1 changed file with 24 additions and 5 deletions.
29 changes: 24 additions & 5 deletions src/closures.c
Expand Up @@ -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);
Expand All @@ -280,16 +280,35 @@ 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;

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

0 comments on commit 8daeed9

Please sign in to comment.