Repository: opencontainers/runc
File: libcontainer/nsenter/cloned_binary.c (C)

Code before:

	/*
	 * Our final option is to create a temporary file the old-school way, and
	 * then unlink it so that nothing else sees it by accident.
	 */
	*fdtype = EFD_FILE;
	fd = mkostemp(template, O_CLOEXEC);
	if (fd >= 0) {
		if (unlink(template) >= 0)
			return fd;
		close(fd);
	}

error:
	*fdtype = EFD_NONE;
	return -1;
}

static int seal_execfd(int *fd, int fdtype)
{
	switch (fdtype) {
	case EFD_MEMFD:
		return fcntl(*fd, F_ADD_SEALS, RUNC_MEMFD_SEALS);
	case EFD_FILE:{
			/* Need to re-open our pseudo-memfd as an O_PATH to avoid execve(2) giving -ETXTBSY. */
			int newfd;
			char fdpath[PATH_MAX] = { 0 };

			if (fchmod(*fd, 0100) < 0)
				return -1;

			if (snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", *fd) < 0)
				return -1;

			newfd = open(fdpath, O_PATH | O_CLOEXEC);
			if (newfd < 0)
				return -1;

			close(*fd);
			*fd = newfd;
			return 0;
		}
	default:
		break;
	}
	return -1;
}

struct bindfd_child_args {
	int sockfd;
	const char *mount_target;

Review comment (bug):
😭 Maybe there is a bug for many years? In some old kernels, we will use `O_TMPFILE` or `mkostemp`, but at this time, the runc state dir has not been created yet. So we will got an error in these old kernels:
`
FATA[0000] nsexec[18089]: could not ensure we are a cloned binary: Permission denied
`

So, we should deal with it.
1) use `/tmp` directly;
or
2) continue to use `getenv("_LIBCONTAINER_STATEDIR")`, but we should create first, and delete it when got an error, I think it's very complex.

Code after:
	if (snprintf(template, sizeof(template), "%s/runc.XXXXXX", prefix) < 0)
		return -1;

	/*
	 * Now try memfd, it's much nicer than actually creating a file in STATEDIR
	 * since it's easily detected thanks to sealing and also doesn't require
	 * assumptions about STATEDIR.
	 */
	*fdtype = EFD_MEMFD;
	/*
	 * On newer kernels we should set MFD_EXEC to indicate we need +x
	 * permissions. Otherwise an admin with vm.memfd_noexec=1 would subtly
	 * break runc. vm.memfd_noexec=2 is a little bit more complicated, see the
	 * comment in is_memfd_unsupported_error() -- the upshot is that doing it
	 * this way works, but only because of two overlapping bugs in the sysctl
	 * implementation.
	 */
	fd = memfd_create(RUNC_MEMFD_COMMENT, MFD_EXEC | MFD_CLOEXEC | MFD_ALLOW_SEALING);
	if (fd < 0 && is_memfd_unsupported_error(errno))
		fd = memfd_create(RUNC_MEMFD_COMMENT, MFD_CLOEXEC | MFD_ALLOW_SEALING);
	if (fd >= 0)
		return fd;
	if (!is_memfd_unsupported_error(errno))
		goto error;

#ifdef O_TMPFILE
	/*
	 * Try O_TMPFILE to avoid races where someone might snatch our file. Note
	 * that O_EXCL isn't actually a security measure here (since you can just
	 * fd re-open it and clear O_EXCL).
	 */
	*fdtype = EFD_FILE;
	fd = open(prefix, O_TMPFILE | O_EXCL | O_RDWR | O_CLOEXEC, 0700);
	if (fd >= 0) {
		struct stat statbuf = { };
		bool working_otmpfile = false;

		/*
		 * open(2) ignores unknown O_* flags -- yeah, I was surprised when I
		 * found this out too. As a result we can't check for EINVAL. However,
		 * if we get nlink != 0 (or EISDIR) then we know that this kernel
		 * doesn't support O_TMPFILE.
		 */
		if (fstat(fd, &statbuf) >= 0)
			working_otmpfile = (statbuf.st_nlink == 0);

		if (working_otmpfile)
			return fd;

		/* Pretend that we got EISDIR since O_TMPFILE failed. */
		close(fd);