nsenter: cloned_binary: use the runc statedir for O_TMPFILE

Writing a file to tmpfs actually incurs a memcg penalty, and thus the
benefit of being able to disable memfd_create(2) with
_LIBCONTAINER_DISABLE_MEMFD_CLONE is fairly minimal -- though it should
be noted that quite a few distributions don't use tmpfs for /tmp (and
instead have it as a regular directory or subvolume of the host
filesystem).

Since runc must have write access to the state directory anyway (and the
state directory is usually not on a tmpfs) we can use that instead of
/tmp -- avoiding potential memcg costs with no real downside.

Signed-off-by: Aleksa Sarai <asarai@suse.de>
This commit is contained in:
Aleksa Sarai 2019-02-19 22:33:09 +11:00
parent 2429d59352
commit af9da0a450
No known key found for this signature in database
GPG Key ID: 9E18AA267DDB8DB4
2 changed files with 10 additions and 3 deletions

View File

@ -481,6 +481,7 @@ func (c *linuxContainer) commandTemplate(p *Process, childPipe *os.File) (*exec.
cmd.ExtraFiles = append(cmd.ExtraFiles, childPipe)
cmd.Env = append(cmd.Env,
fmt.Sprintf("_LIBCONTAINER_INITPIPE=%d", stdioFdCount+len(cmd.ExtraFiles)-1),
fmt.Sprintf("_LIBCONTAINER_STATEDIR=%s", c.root),
)
// NOTE: when running a container with no PID namespace and the parent process spawning the container is
// PID1 the pdeathsig is being delivered to the container's init process by the kernel for some reason

View File

@ -217,8 +217,14 @@ enum {
static int make_execfd(int *fdtype)
{
int fd;
char template[] = "/tmp/runc-cloned-binary.XXXXXX";
int fd = -1;
char template[PATH_MAX] = {0};
char *prefix = secure_getenv("_LIBCONTAINER_STATEDIR");
if (!prefix || *prefix != '/')
prefix = "/tmp";
if (snprintf(template, sizeof(template), "%s/runc.XXXXXX", prefix) < 0)
return -1;
/*
* Try memfd first, it's much nicer since it's easily detected thanks to
@ -238,7 +244,7 @@ static int make_execfd(int *fdtype)
* fd re-open it and clear O_EXCL).
*/
*fdtype = EFD_FILE;
fd = open("/tmp", O_TMPFILE | O_EXCL | O_RDWR | O_CLOEXEC, 0700);
fd = open(prefix, O_TMPFILE | O_EXCL | O_RDWR | O_CLOEXEC, 0700);
if (fd >= 0) {
struct stat statbuf = {};
bool working_otmpfile = false;