Unverified Commit c0c183b3 by Stéphane Graber Committed by GitHub

Merge pull request #3331 from brauner/2020-03-27/fixes

tree-wide: fixes
parents d4a5002b f7a97743
...@@ -1326,8 +1326,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, ...@@ -1326,8 +1326,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function,
} }
/* close unneeded file descriptors */ /* close unneeded file descriptors */
close(ipc_sockets[0]); close_prot_errno_disarm(ipc_sockets[0]);
ipc_sockets[0] = -EBADF;
if (options->attach_flags & LXC_ATTACH_TERMINAL) { if (options->attach_flags & LXC_ATTACH_TERMINAL) {
lxc_attach_terminal_close_master(&terminal); lxc_attach_terminal_close_master(&terminal);
......
...@@ -2057,8 +2057,11 @@ static inline char *build_full_cgpath_from_monitorpath(struct hierarchy *h, ...@@ -2057,8 +2057,11 @@ static inline char *build_full_cgpath_from_monitorpath(struct hierarchy *h,
return must_make_path(h->mountpoint, inpath, filename, NULL); return must_make_path(h->mountpoint, inpath, filename, NULL);
} }
static int cgroup_attach_leaf(const struct lxc_conf *conf, int unified_fd, pid_t pid) #define LXC_UNIFIED_ATTACH_CGROUP_LEN STRLITERALLEN("/lxc-1000/cgroup.procs")
static int cgroup_attach_leaf(const struct lxc_conf *conf, char *unified_path,
int unified_fd, pid_t pid)
{ {
__do_free char *path = NULL;
int idx = 1; int idx = 1;
int ret; int ret;
char pidstr[INTTYPE_TO_STRLEN(int64_t) + 1]; char pidstr[INTTYPE_TO_STRLEN(int64_t) + 1];
...@@ -2069,6 +2072,11 @@ static int cgroup_attach_leaf(const struct lxc_conf *conf, int unified_fd, pid_t ...@@ -2069,6 +2072,11 @@ static int cgroup_attach_leaf(const struct lxc_conf *conf, int unified_fd, pid_t
if (ret < 0 && errno != EEXIST) if (ret < 0 && errno != EEXIST)
return log_error_errno(-1, errno, "Failed to create leaf cgroup \"lxc\""); return log_error_errno(-1, errno, "Failed to create leaf cgroup \"lxc\"");
path = must_make_path(unified_path, "lxc", NULL);
ret = chown_mapped_root(path, conf);
if (ret < 0)
return log_error_errno(-1, errno, "Failed to chown \"%s\"", path);
pidstr_len = sprintf(pidstr, INT64_FMT, (int64_t)pid); pidstr_len = sprintf(pidstr, INT64_FMT, (int64_t)pid);
ret = lxc_writeat(unified_fd, "lxc/cgroup.procs", pidstr, pidstr_len); ret = lxc_writeat(unified_fd, "lxc/cgroup.procs", pidstr, pidstr_len);
if (ret < 0) if (ret < 0)
...@@ -2080,9 +2088,10 @@ static int cgroup_attach_leaf(const struct lxc_conf *conf, int unified_fd, pid_t ...@@ -2080,9 +2088,10 @@ static int cgroup_attach_leaf(const struct lxc_conf *conf, int unified_fd, pid_t
if (errno != EBUSY) if (errno != EBUSY)
return log_error_errno(-1, errno, "Failed to attach to unified cgroup"); return log_error_errno(-1, errno, "Failed to attach to unified cgroup");
free_disarm(path);
do { do {
bool rm = false; bool rm = false;
char attach_cgroup[STRLITERALLEN("lxc-1000/cgroup.procs") + 1]; char attach_cgroup[LXC_UNIFIED_ATTACH_CGROUP_LEN + 1];
char *slash; char *slash;
sprintf(attach_cgroup, "lxc-%d/cgroup.procs", idx); sprintf(attach_cgroup, "lxc-%d/cgroup.procs", idx);
...@@ -2097,6 +2106,12 @@ static int cgroup_attach_leaf(const struct lxc_conf *conf, int unified_fd, pid_t ...@@ -2097,6 +2106,12 @@ static int cgroup_attach_leaf(const struct lxc_conf *conf, int unified_fd, pid_t
*slash = '/'; *slash = '/';
path = must_make_path(unified_path, attach_cgroup, NULL);
ret = chown_mapped_root(path, conf);
if (ret < 0)
return log_error_errno(-1, errno, "Failed to chown \"%s\"", path);
free_disarm(path);
ret = lxc_writeat(unified_fd, attach_cgroup, pidstr, pidstr_len); ret = lxc_writeat(unified_fd, attach_cgroup, pidstr, pidstr_len);
if (ret == 0) if (ret == 0)
return 0; return 0;
...@@ -2114,47 +2129,14 @@ static int cgroup_attach_leaf(const struct lxc_conf *conf, int unified_fd, pid_t ...@@ -2114,47 +2129,14 @@ static int cgroup_attach_leaf(const struct lxc_conf *conf, int unified_fd, pid_t
return log_error_errno(-1, errno, "Failed to attach to unified cgroup"); return log_error_errno(-1, errno, "Failed to attach to unified cgroup");
} }
struct userns_exec_unified_attach_data {
const struct lxc_conf *conf;
int unified_fd;
pid_t pid;
uid_t origuid;
};
static int cgroup_unified_attach_wrapper(void *data)
{
struct userns_exec_unified_attach_data *args = data;
uid_t nsuid;
gid_t nsgid;
int ret;
if (!args->conf || args->unified_fd < 0 || args->pid <= 0)
return ret_errno(EINVAL);
if (!lxc_setgroups(0, NULL) && errno != EPERM)
return log_error_errno(-1, errno, "Failed to setgroups(0, NULL)");
nsuid = (args->conf->root_nsuid_map != NULL) ? 0 : args->conf->init_uid;
nsgid = (args->conf->root_nsgid_map != NULL) ? 0 : args->conf->init_gid;
ret = setresgid(nsgid, nsgid, nsgid);
if (ret < 0)
return log_error_errno(-1, errno, "Failed to setresgid(%d, %d, %d)",
(int)nsgid, (int)nsgid, (int)nsgid);
ret = setresuid(nsuid, nsuid, nsuid);
if (ret < 0)
return log_error_errno(-1, errno, "Failed to setresuid(%d, %d, %d)",
(int)nsuid, (int)nsuid, (int)nsuid);
return cgroup_attach_leaf(args->conf, args->unified_fd, args->pid);
}
int cgroup_attach(const struct lxc_conf *conf, const char *name, int cgroup_attach(const struct lxc_conf *conf, const char *name,
const char *lxcpath, pid_t pid) const char *lxcpath, pid_t pid)
{ {
__do_close int unified_fd = -EBADF; __do_close int unified_fd = -EBADF;
__do_free char *buf = NULL;
int ret; int ret;
ssize_t len;
struct stat st;
if (!conf || !name || !lxcpath || pid <= 0) if (!conf || !name || !lxcpath || pid <= 0)
return ret_errno(EINVAL); return ret_errno(EINVAL);
...@@ -2163,20 +2145,24 @@ int cgroup_attach(const struct lxc_conf *conf, const char *name, ...@@ -2163,20 +2145,24 @@ int cgroup_attach(const struct lxc_conf *conf, const char *name,
if (unified_fd < 0) if (unified_fd < 0)
return ret_errno(EBADF); return ret_errno(EBADF);
if (!lxc_list_empty(&conf->id_map)) { ret = fstatat(unified_fd, "", &st, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW);
struct userns_exec_unified_attach_data args = { if (ret < 0)
.conf = conf, return -errno;
.unified_fd = unified_fd,
.pid = pid,
};
ret = userns_exec_1(conf, cgroup_unified_attach_wrapper, &args, if (st.st_size == 0)
"cgroup_unified_attach_wrapper"); return ret_errno(EINVAL);
} else {
ret = cgroup_attach_leaf(conf, unified_fd, pid);
}
return ret; buf = zalloc(st.st_size);
if (!buf)
return ret_errno(ENOMEM);
len = readlinkat(unified_fd, "", buf, st.st_size);
if (len < 0)
return -errno;
if (len >= st.st_size)
return ret_errno(E2BIG);
return cgroup_attach_leaf(conf, buf, unified_fd, pid);
} }
/* Technically, we're always at a delegation boundary here (This is especially /* Technically, we're always at a delegation boundary here (This is especially
...@@ -2218,20 +2204,7 @@ static int __cg_unified_attach(const struct hierarchy *h, ...@@ -2218,20 +2204,7 @@ static int __cg_unified_attach(const struct hierarchy *h,
if (unified_fd < 0) if (unified_fd < 0)
return ret_errno(EBADF); return ret_errno(EBADF);
if (!lxc_list_empty(&conf->id_map)) { return cgroup_attach_leaf(conf, path, unified_fd, pid);
struct userns_exec_unified_attach_data args = {
.conf = conf,
.unified_fd = unified_fd,
.pid = pid,
};
ret = userns_exec_1(conf, cgroup_unified_attach_wrapper, &args,
"cgroup_unified_attach_wrapper");
} else {
ret = cgroup_attach_leaf(conf, unified_fd, pid);
}
return ret;
} }
__cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops,
......
...@@ -1450,7 +1450,7 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data, ...@@ -1450,7 +1450,7 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
if (errno == EACCES) { if (errno == EACCES) {
/* We don't care for the peer, just send and close. */ /* We don't care for the peer, just send and close. */
struct lxc_cmd_rsp rsp = { struct lxc_cmd_rsp rsp = {
.ret = ret, .ret = -EPERM,
}; };
lxc_cmd_rsp_send(fd, &rsp); lxc_cmd_rsp_send(fd, &rsp);
...@@ -1464,14 +1464,11 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data, ...@@ -1464,14 +1464,11 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
if (ret != sizeof(req)) { if (ret != sizeof(req)) {
WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req.cmd)); WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req.cmd));
ret = -1;
goto out_close; goto out_close;
} }
if ((req.datalen > LXC_CMD_DATA_MAX) && (req.cmd != LXC_CMD_CONSOLE_LOG)) { if ((req.datalen > LXC_CMD_DATA_MAX) && (req.cmd != LXC_CMD_CONSOLE_LOG)) {
ERROR("Received command data length %d is too large for command \"%s\"", req.datalen, lxc_cmd_str(req.cmd)); ERROR("Received command data length %d is too large for command \"%s\"", req.datalen, lxc_cmd_str(req.cmd));
errno = EFBIG;
ret = -EFBIG;
goto out_close; goto out_close;
} }
...@@ -1480,7 +1477,6 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data, ...@@ -1480,7 +1477,6 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
ret = lxc_recv_nointr(fd, reqdata, req.datalen, 0); ret = lxc_recv_nointr(fd, reqdata, req.datalen, 0);
if (ret != req.datalen) { if (ret != req.datalen) {
WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req.cmd)); WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req.cmd));
ret = LXC_MAINLOOP_ERROR;
goto out_close; goto out_close;
} }
...@@ -1490,12 +1486,11 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data, ...@@ -1490,12 +1486,11 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
ret = lxc_cmd_process(fd, &req, handler, descr); ret = lxc_cmd_process(fd, &req, handler, descr);
if (ret) { if (ret) {
/* This is not an error, but only a request to close fd. */ /* This is not an error, but only a request to close fd. */
ret = LXC_MAINLOOP_CONTINUE;
goto out_close; goto out_close;
} }
out: out:
return ret; return LXC_MAINLOOP_CONTINUE;
out_close: out_close:
lxc_cmd_fd_cleanup(fd, handler, descr, req.cmd); lxc_cmd_fd_cleanup(fd, handler, descr, req.cmd);
......
...@@ -1478,10 +1478,8 @@ retry: ...@@ -1478,10 +1478,8 @@ retry:
SYSERROR("Failed to send seccomp notification"); SYSERROR("Failed to send seccomp notification");
out: out:
return 0;
#else
return -ENOSYS;
#endif #endif
return LXC_MAINLOOP_CONTINUE;
} }
void seccomp_conf_init(struct lxc_conf *conf) void seccomp_conf_init(struct lxc_conf *conf)
......
...@@ -335,7 +335,7 @@ static int signal_handler(int fd, uint32_t events, void *data, ...@@ -335,7 +335,7 @@ static int signal_handler(int fd, uint32_t events, void *data,
return log_error(LXC_MAINLOOP_ERROR, "Failed to read signal info from signal file descriptor %d", fd); return log_error(LXC_MAINLOOP_ERROR, "Failed to read signal info from signal file descriptor %d", fd);
if (ret != sizeof(siginfo)) if (ret != sizeof(siginfo))
return log_error(-EINVAL, "Unexpected size for struct signalfd_siginfo"); return log_error(LXC_MAINLOOP_ERROR, "Unexpected size for struct signalfd_siginfo");
/* Check whether init is running. */ /* Check whether init is running. */
info.si_pid = 0; info.si_pid = 0;
......
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