Unverified Commit 2d8bd1db by Stéphane Graber Committed by GitHub

Merge pull request #2865 from brauner/2019-02-18/rexec_improve_fallbacks

rexec: try sendfile() fallback to fd_to_fd()
parents cd1372e2 5e6e38bd
...@@ -105,8 +105,11 @@ static int is_memfd(void) ...@@ -105,8 +105,11 @@ static int is_memfd(void)
static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name) 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; __do_close_prot_errno int execfd = -EBADF, fd = -EBADF, memfd = -EBADF,
tmpfd = -EBADF;
int ret; int ret;
ssize_t bytes_sent = 0;
struct stat st = {0};
memfd = memfd_create(memfd_name, MFD_ALLOW_SEALING | MFD_CLOEXEC); memfd = memfd_create(memfd_name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
if (memfd < 0) { if (memfd < 0) {
...@@ -131,35 +134,35 @@ static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name) ...@@ -131,35 +134,35 @@ static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name)
return; return;
/* sendfile() handles up to 2GB. */ /* sendfile() handles up to 2GB. */
if (memfd >= 0) { ret = fstat(fd, &st);
ssize_t bytes_sent = 0; if (ret)
struct stat st = {0}; return;
ret = fstat(fd, &st); while (bytes_sent < st.st_size) {
if (ret) ssize_t sent;
return;
while (bytes_sent < st.st_size) { sent = lxc_sendfile_nointr(memfd >= 0 ? memfd : tmpfd, fd, NULL,
ssize_t sent; st.st_size - bytes_sent);
sent = lxc_sendfile_nointr(memfd, fd, NULL, if (sent < 0) {
st.st_size - bytes_sent); /* Fallback to shoveling data between kernel- and
if (sent < 0) * userspace.
return; */
bytes_sent += sent; lseek(fd, 0, SEEK_SET);
if (fd_to_fd(fd, memfd >= 0 ? memfd : tmpfd))
break;
return;
} }
} else if (fd_to_fd(fd, tmpfd)) { bytes_sent += sent;
return;
} }
close_prot_errno_disarm(fd); close_prot_errno_disarm(fd);
if (memfd >= 0 && fcntl(memfd, F_ADD_SEALS, LXC_MEMFD_REXEC_SEALS))
return;
if (memfd >= 0) { if (memfd >= 0) {
fexecve(memfd, argv, envp); if (fcntl(memfd, F_ADD_SEALS, LXC_MEMFD_REXEC_SEALS))
return;
execfd = memfd;
} else { } else {
__do_close_prot_errno int execfd = -EBADF;
char procfd[LXC_PROC_PID_FD_LEN]; char procfd[LXC_PROC_PID_FD_LEN];
ret = snprintf(procfd, sizeof(procfd), "/proc/self/fd/%d", tmpfd); ret = snprintf(procfd, sizeof(procfd), "/proc/self/fd/%d", tmpfd);
...@@ -168,11 +171,12 @@ static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name) ...@@ -168,11 +171,12 @@ static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name)
execfd = open(procfd, O_PATH | O_CLOEXEC); execfd = open(procfd, O_PATH | O_CLOEXEC);
close_prot_errno_disarm(tmpfd); close_prot_errno_disarm(tmpfd);
if (execfd < 0)
return;
fexecve(execfd, argv, envp);
} }
if (execfd < 0)
return;
fexecve(execfd, argv, envp);
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment