mode_t msk;
msk = umask(0022);
- fd = mkostemp(template, O_CLOEXEC);
+ fd = mkstemp(template);
umask(msk);
if (fd < 0)
return -1;
return NULL;
}
-
-int fd_to_fd(int from, int to)
-{
- for (;;) {
- uint8_t buf[PATH_MAX];
- uint8_t *p = buf;
- ssize_t bytes_to_write;
- ssize_t bytes_read;
-
- bytes_read = lxc_read_nointr(from, buf, sizeof buf);
- if (bytes_read < 0)
- return -1;
- if (bytes_read == 0)
- break;
-
- bytes_to_write = (size_t)bytes_read;
- do {
- ssize_t bytes_written;
-
- bytes_written = lxc_write_nointr(to, p, bytes_to_write);
- if (bytes_written < 0)
- return -1;
-
- bytes_to_write -= bytes_written;
- p += bytes_written;
- } while (bytes_to_write > 0);
- }
-
- return 0;
-}
static int is_memfd(void)
{
__do_close_prot_errno int fd = -EBADF;
- int seals;
+ int saved_errno, seals;
fd = open("/proc/self/exe", O_RDONLY | O_CLOEXEC);
if (fd < 0)
return -ENOTRECOVERABLE;
seals = fcntl(fd, F_GET_SEALS);
- if (seals < 0) {
- struct stat s = {0};
-
- if (fstat(fd, &s) == 0) {
- fprintf(stderr, "AAAAA: %ld\n", (long)s.st_nlink);
- return (s.st_nlink == 0);
- }
-
+ if (seals < 0)
return -EINVAL;
- }
return seals == LXC_MEMFD_REXEC_SEALS;
}
static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name)
{
- __do_close_prot_errno int fd = -EBADF, memfd = -EBADF, tmpfd = -EBADF;
- int ret;
+ __do_close_prot_errno int fd = -EBADF, memfd = -EBADF;
+ int saved_errno;
+ ssize_t bytes_sent;
memfd = memfd_create(memfd_name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
- if (memfd < 0) {
- char template[PATH_MAX];
-
- ret = snprintf(template, sizeof(template),
- P_tmpdir "/.%s_XXXXXX", memfd_name);
- if (ret < 0 || (size_t)ret >= sizeof(template))
- return;
-
- tmpfd = lxc_make_tmpfile(template, true);
- if (tmpfd < 0)
- return;
-
- ret = fchmod(tmpfd, 0700);
- if (ret)
- return;
- }
+ if (memfd < 0)
+ return;
fd = open("/proc/self/exe", O_RDONLY | O_CLOEXEC);
if (fd < 0)
return;
/* sendfile() handles up to 2GB. */
- if (memfd >= 0) {
- ssize_t bytes_sent = 0;
- struct stat st = {0};
-
- ret = fstat(fd, &st);
- if (ret)
- return;
-
- while (bytes_sent < st.st_size) {
- ssize_t sent;
- sent = lxc_sendfile_nointr(memfd, fd, NULL,
- st.st_size - bytes_sent);
- if (sent < 0)
- return;
- bytes_sent += sent;
- }
- } else if (fd_to_fd(fd, tmpfd)) {
+ bytes_sent = lxc_sendfile_nointr(memfd, fd, NULL, LXC_SENDFILE_MAX);
+ if (bytes_sent < 0)
return;
- }
- close_prot_errno_disarm(fd);
-
- if (memfd >= 0 && fcntl(memfd, F_ADD_SEALS, LXC_MEMFD_REXEC_SEALS))
+ if (fcntl(memfd, F_ADD_SEALS, LXC_MEMFD_REXEC_SEALS))
return;
- if (memfd >= 0) {
- fexecve(memfd, argv, envp);
- } else {
- __do_close_prot_errno int execfd = -EBADF;
- char procfd[LXC_PROC_PID_FD_LEN];
-
- ret = snprintf(procfd, sizeof(procfd), "/proc/self/fd/%d", tmpfd);
- if (ret < 0 || (size_t)ret >= sizeof(procfd))
- return;
-
- execfd = open(procfd, O_PATH | O_CLOEXEC);
- close_prot_errno_disarm(tmpfd);
- if (execfd < 0)
- return;
-
- fexecve(execfd, argv, envp);
- }
+ fexecve(memfd, argv, envp);
}
/*