Unverified Commit 010a85d1 by Christian Brauner Committed by GitHub

Merge pull request #2482 from 2xsec/bugfix

error handling cleanups #2471
parents 8fd3e219 9044b79e
...@@ -74,30 +74,28 @@ int lxc_abstract_unix_open(const char *path, int type, int flags) ...@@ -74,30 +74,28 @@ int lxc_abstract_unix_open(const char *path, int type, int flags)
ret = bind(fd, (struct sockaddr *)&addr, ret = bind(fd, (struct sockaddr *)&addr,
offsetof(struct sockaddr_un, sun_path) + len + 1); offsetof(struct sockaddr_un, sun_path) + len + 1);
if (ret < 0) { if (ret < 0) {
int tmp = errno; int saved_erron = errno;
close(fd); close(fd);
errno = tmp; errno = saved_erron;
return -1; return -1;
} }
if (type == SOCK_STREAM) { if (type == SOCK_STREAM) {
ret = listen(fd, 100); ret = listen(fd, 100);
if (ret < 0) { if (ret < 0) {
int tmp = errno; int saved_erron = errno;
close(fd); close(fd);
errno = tmp; errno = saved_erron;
return -1; return -1;
} }
} }
return fd; return fd;
} }
int lxc_abstract_unix_close(int fd) void lxc_abstract_unix_close(int fd)
{ {
close(fd); close(fd);
return 0;
} }
int lxc_abstract_unix_connect(const char *path) int lxc_abstract_unix_connect(const char *path)
...@@ -128,7 +126,9 @@ int lxc_abstract_unix_connect(const char *path) ...@@ -128,7 +126,9 @@ int lxc_abstract_unix_connect(const char *path)
ret = connect(fd, (struct sockaddr *)&addr, ret = connect(fd, (struct sockaddr *)&addr,
offsetof(struct sockaddr_un, sun_path) + len + 1); offsetof(struct sockaddr_un, sun_path) + len + 1);
if (ret < 0) { if (ret < 0) {
int saved_errno = errno;
close(fd); close(fd);
errno = saved_errno;
return -1; return -1;
} }
...@@ -150,8 +150,10 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds, ...@@ -150,8 +150,10 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
memset(&iov, 0, sizeof(iov)); memset(&iov, 0, sizeof(iov));
cmsgbuf = malloc(cmsgbufsize); cmsgbuf = malloc(cmsgbufsize);
if (!cmsgbuf) if (!cmsgbuf) {
errno = ENOMEM;
return -1; return -1;
}
msg.msg_control = cmsgbuf; msg.msg_control = cmsgbuf;
msg.msg_controllen = cmsgbufsize; msg.msg_controllen = cmsgbufsize;
...@@ -190,8 +192,10 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds, ...@@ -190,8 +192,10 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
memset(&iov, 0, sizeof(iov)); memset(&iov, 0, sizeof(iov));
cmsgbuf = malloc(cmsgbufsize); cmsgbuf = malloc(cmsgbufsize);
if (!cmsgbuf) if (!cmsgbuf) {
errno = ENOMEM;
return -1; return -1;
}
msg.msg_control = cmsgbuf; msg.msg_control = cmsgbuf;
msg.msg_controllen = cmsgbufsize; msg.msg_controllen = cmsgbufsize;
...@@ -209,9 +213,8 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds, ...@@ -209,9 +213,8 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
memset(recvfds, -1, num_recvfds * sizeof(int)); memset(recvfds, -1, num_recvfds * sizeof(int));
if (cmsg && cmsg->cmsg_len == CMSG_LEN(num_recvfds * sizeof(int)) && if (cmsg && cmsg->cmsg_len == CMSG_LEN(num_recvfds * sizeof(int)) &&
cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
memcpy(recvfds, CMSG_DATA(cmsg), num_recvfds * sizeof(int)); memcpy(recvfds, CMSG_DATA(cmsg), num_recvfds * sizeof(int));
}
out: out:
free(cmsgbuf); free(cmsgbuf);
...@@ -281,10 +284,12 @@ int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size) ...@@ -281,10 +284,12 @@ int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size)
memcpy(&cred, CMSG_DATA(cmsg), sizeof(cred)); memcpy(&cred, CMSG_DATA(cmsg), sizeof(cred));
if (cred.uid && if (cred.uid &&
(cred.uid != getuid() || cred.gid != getgid())) { (cred.uid != getuid() || cred.gid != getgid())) {
INFO("message denied for '%d/%d'", cred.uid, cred.gid); INFO("Message denied for '%d/%d'", cred.uid, cred.gid);
return -EACCES; errno = EACCES;
return -1;
} }
} }
out: out:
return ret; return ret;
} }
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
/* does not enforce \0-termination */ /* does not enforce \0-termination */
extern int lxc_abstract_unix_open(const char *path, int type, int flags); extern int lxc_abstract_unix_open(const char *path, int type, int flags);
extern int lxc_abstract_unix_close(int fd); extern void lxc_abstract_unix_close(int fd);
/* does not enforce \0-termination */ /* does not enforce \0-termination */
extern int lxc_abstract_unix_connect(const char *path); extern int lxc_abstract_unix_connect(const char *path);
extern int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds, extern int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
......
...@@ -828,8 +828,13 @@ static int attach_child_main(struct attach_clone_payload *payload) ...@@ -828,8 +828,13 @@ static int attach_child_main(struct attach_clone_payload *payload)
*/ */
if (needs_lsm) { if (needs_lsm) {
ret = lxc_abstract_unix_recv_fds(payload->ipc_socket, &lsm_fd, 1, NULL, 0); ret = lxc_abstract_unix_recv_fds(payload->ipc_socket, &lsm_fd, 1, NULL, 0);
if (ret <= 0) if (ret <= 0) {
if (ret < 0)
SYSERROR("Failed to receive lsm label fd");
goto on_error; goto on_error;
}
TRACE("Received LSM label file descriptor %d from parent", lsm_fd); TRACE("Received LSM label file descriptor %d from parent", lsm_fd);
} }
...@@ -1330,11 +1335,15 @@ int lxc_attach(const char *name, const char *lxcpath, ...@@ -1330,11 +1335,15 @@ int lxc_attach(const char *name, const char *lxcpath,
/* Send child fd of the LSM security module to write to. */ /* Send child fd of the LSM security module to write to. */
ret = lxc_abstract_unix_send_fds(ipc_sockets[0], &labelfd, 1, NULL, 0); ret = lxc_abstract_unix_send_fds(ipc_sockets[0], &labelfd, 1, NULL, 0);
close(labelfd);
if (ret <= 0) { if (ret <= 0) {
SYSERROR("%d", (int)ret); if (ret < 0)
SYSERROR("Failed to send lsm label fd");
close(labelfd);
goto close_mainloop; goto close_mainloop;
} }
close(labelfd);
TRACE("Sent LSM label file descriptor %d to child", labelfd); TRACE("Sent LSM label file descriptor %d to child", labelfd);
} }
......
...@@ -97,8 +97,8 @@ static int lxc_monitord_fifo_create(struct lxc_monitor *mon) ...@@ -97,8 +97,8 @@ static int lxc_monitord_fifo_create(struct lxc_monitor *mon)
mon->fifofd = open(fifo_path, O_RDWR); mon->fifofd = open(fifo_path, O_RDWR);
if (mon->fifofd < 0) { if (mon->fifofd < 0) {
SYSERROR("Failed to open monitor fifo %s", fifo_path);
unlink(fifo_path); unlink(fifo_path);
ERROR("Failed to open monitor fifo.");
return -1; return -1;
} }
...@@ -106,12 +106,14 @@ static int lxc_monitord_fifo_create(struct lxc_monitor *mon) ...@@ -106,12 +106,14 @@ static int lxc_monitord_fifo_create(struct lxc_monitor *mon)
lk.l_whence = SEEK_SET; lk.l_whence = SEEK_SET;
lk.l_start = 0; lk.l_start = 0;
lk.l_len = 0; lk.l_len = 0;
if (fcntl(mon->fifofd, F_SETLK, &lk) != 0) { if (fcntl(mon->fifofd, F_SETLK, &lk) != 0) {
/* another lxc-monitord is already running, don't start up */ /* another lxc-monitord is already running, don't start up */
DEBUG("lxc-monitord already running on lxcpath %s.", mon->lxcpath); SYSDEBUG("lxc-monitord already running on lxcpath %s", mon->lxcpath);
close(mon->fifofd); close(mon->fifofd);
return -1; return -1;
} }
return 0; return 0;
} }
...@@ -132,15 +134,15 @@ static void lxc_monitord_sockfd_remove(struct lxc_monitor *mon, int fd) { ...@@ -132,15 +134,15 @@ static void lxc_monitord_sockfd_remove(struct lxc_monitor *mon, int fd) {
int i; int i;
if (lxc_mainloop_del_handler(&mon->descr, fd)) if (lxc_mainloop_del_handler(&mon->descr, fd))
CRIT("File descriptor %d not found in mainloop.", fd); CRIT("File descriptor %d not found in mainloop", fd);
close(fd); close(fd);
for (i = 0; i < mon->clientfds_cnt; i++) { for (i = 0; i < mon->clientfds_cnt; i++)
if (mon->clientfds[i] == fd) if (mon->clientfds[i] == fd)
break; break;
}
if (i >= mon->clientfds_cnt) { if (i >= mon->clientfds_cnt) {
CRIT("File descriptor %d not found in clients array.", fd); CRIT("File descriptor %d not found in clients array", fd);
lxc_monitord_cleanup(); lxc_monitord_cleanup();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
...@@ -166,6 +168,7 @@ static int lxc_monitord_sock_handler(int fd, uint32_t events, void *data, ...@@ -166,6 +168,7 @@ static int lxc_monitord_sock_handler(int fd, uint32_t events, void *data,
if (events & EPOLLHUP) if (events & EPOLLHUP)
lxc_monitord_sockfd_remove(mon, fd); lxc_monitord_sockfd_remove(mon, fd);
return quit; return quit;
} }
...@@ -180,53 +183,55 @@ static int lxc_monitord_sock_accept(int fd, uint32_t events, void *data, ...@@ -180,53 +183,55 @@ static int lxc_monitord_sock_accept(int fd, uint32_t events, void *data,
ret = LXC_MAINLOOP_ERROR; ret = LXC_MAINLOOP_ERROR;
clientfd = accept(fd, NULL, 0); clientfd = accept(fd, NULL, 0);
if (clientfd < 0) { if (clientfd < 0) {
SYSERROR("Failed to accept connection for client file descriptor %d.", fd); SYSERROR("Failed to accept connection for client file descriptor %d", fd);
goto out; goto out;
} }
if (fcntl(clientfd, F_SETFD, FD_CLOEXEC)) { if (fcntl(clientfd, F_SETFD, FD_CLOEXEC)) {
SYSERROR("Failed to set FD_CLOEXEC on client socket connection %d.", clientfd); SYSERROR("Failed to set FD_CLOEXEC on client socket connection %d", clientfd);
goto err1; goto err1;
} }
if (getsockopt(clientfd, SOL_SOCKET, SO_PEERCRED, &cred, &credsz)) if (getsockopt(clientfd, SOL_SOCKET, SO_PEERCRED, &cred, &credsz)) {
{ SYSERROR("Failed to get credentials on client socket connection %d", clientfd);
ERROR("Failed to get credentials on client socket connection %d.", clientfd);
goto err1; goto err1;
} }
if (cred.uid && cred.uid != geteuid()) { if (cred.uid && cred.uid != geteuid()) {
WARN("Monitor denied for uid %d on client socket connection %d.", cred.uid, clientfd); WARN("Monitor denied for uid %d on client socket connection %d", cred.uid, clientfd);
ret = -EACCES;
goto err1; goto err1;
} }
if (mon->clientfds_cnt + 1 > mon->clientfds_size) { if (mon->clientfds_cnt + 1 > mon->clientfds_size) {
int *clientfds; int *clientfds;
clientfds = realloc(mon->clientfds, clientfds = realloc(mon->clientfds,
(mon->clientfds_size + CLIENTFDS_CHUNK) * sizeof(mon->clientfds[0])); (mon->clientfds_size + CLIENTFDS_CHUNK) * sizeof(mon->clientfds[0]));
if (clientfds == NULL) { if (clientfds == NULL) {
ERROR("Failed to realloc memory for %d client file " ERROR("Failed to realloc memory for %d client file descriptors",
"descriptors.",
mon->clientfds_size + CLIENTFDS_CHUNK); mon->clientfds_size + CLIENTFDS_CHUNK);
goto err1; goto err1;
} }
mon->clientfds = clientfds; mon->clientfds = clientfds;
mon->clientfds_size += CLIENTFDS_CHUNK; mon->clientfds_size += CLIENTFDS_CHUNK;
} }
ret = lxc_mainloop_add_handler(&mon->descr, clientfd, ret = lxc_mainloop_add_handler(&mon->descr, clientfd,
lxc_monitord_sock_handler, mon); lxc_monitord_sock_handler, mon);
if (ret) { if (ret < 0) {
ERROR("Failed to add socket handler."); ERROR("Failed to add socket handler");
goto err1; goto err1;
} }
mon->clientfds[mon->clientfds_cnt++] = clientfd; mon->clientfds[mon->clientfds_cnt++] = clientfd;
INFO("Accepted client file descriptor %d. Number of accepted file descriptors is now %d.", clientfd, mon->clientfds_cnt); INFO("Accepted client file descriptor %d. Number of accepted file descriptors is now %d",
clientfd, mon->clientfds_cnt);
goto out; goto out;
err1: err1:
close(clientfd); close(clientfd);
out: out:
return ret; return ret;
} }
...@@ -255,8 +260,10 @@ static int lxc_monitord_sock_delete(struct lxc_monitor *mon) ...@@ -255,8 +260,10 @@ static int lxc_monitord_sock_delete(struct lxc_monitor *mon)
if (lxc_monitor_sock_name(mon->lxcpath, &addr) < 0) if (lxc_monitor_sock_name(mon->lxcpath, &addr) < 0)
return -1; return -1;
if (addr.sun_path[0]) if (addr.sun_path[0])
unlink(addr.sun_path); unlink(addr.sun_path);
return 0; return 0;
} }
...@@ -268,8 +275,7 @@ static int lxc_monitord_create(struct lxc_monitor *mon) ...@@ -268,8 +275,7 @@ static int lxc_monitord_create(struct lxc_monitor *mon)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = lxc_monitord_sock_create(mon); return lxc_monitord_sock_create(mon);
return ret;
} }
static void lxc_monitord_delete(struct lxc_monitor *mon) static void lxc_monitord_delete(struct lxc_monitor *mon)
...@@ -277,7 +283,7 @@ static void lxc_monitord_delete(struct lxc_monitor *mon) ...@@ -277,7 +283,7 @@ static void lxc_monitord_delete(struct lxc_monitor *mon)
int i; int i;
lxc_mainloop_del_handler(&mon->descr, mon->listenfd); lxc_mainloop_del_handler(&mon->descr, mon->listenfd);
close(mon->listenfd); lxc_abstract_unix_close(mon->listenfd);
lxc_monitord_sock_delete(mon); lxc_monitord_sock_delete(mon);
lxc_mainloop_del_handler(&mon->descr, mon->fifofd); lxc_mainloop_del_handler(&mon->descr, mon->fifofd);
...@@ -288,6 +294,7 @@ static void lxc_monitord_delete(struct lxc_monitor *mon) ...@@ -288,6 +294,7 @@ static void lxc_monitord_delete(struct lxc_monitor *mon)
lxc_mainloop_del_handler(&mon->descr, mon->clientfds[i]); lxc_mainloop_del_handler(&mon->descr, mon->clientfds[i]);
close(mon->clientfds[i]); close(mon->clientfds[i]);
} }
mon->clientfds_cnt = 0; mon->clientfds_cnt = 0;
} }
...@@ -321,14 +328,14 @@ static int lxc_monitord_mainloop_add(struct lxc_monitor *mon) ...@@ -321,14 +328,14 @@ static int lxc_monitord_mainloop_add(struct lxc_monitor *mon)
ret = lxc_mainloop_add_handler(&mon->descr, mon->fifofd, ret = lxc_mainloop_add_handler(&mon->descr, mon->fifofd,
lxc_monitord_fifo_handler, mon); lxc_monitord_fifo_handler, mon);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to add to mainloop monitor handler for fifo."); ERROR("Failed to add to mainloop monitor handler for fifo");
return -1; return -1;
} }
ret = lxc_mainloop_add_handler(&mon->descr, mon->listenfd, ret = lxc_mainloop_add_handler(&mon->descr, mon->listenfd,
lxc_monitord_sock_accept, mon); lxc_monitord_sock_accept, mon);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to add to mainloop monitor handler for listen socket."); ERROR("Failed to add to mainloop monitor handler for listen socket");
return -1; return -1;
} }
...@@ -374,9 +381,10 @@ int main(int argc, char *argv[]) ...@@ -374,9 +381,10 @@ int main(int argc, char *argv[])
log.prefix = "lxc-monitord"; log.prefix = "lxc-monitord";
log.quiet = 0; log.quiet = 0;
log.lxcpath = lxcpath; log.lxcpath = lxcpath;
ret = lxc_log_init(&log); ret = lxc_log_init(&log);
if (ret) if (ret)
INFO("Failed to open log file %s, log will be lost.", lxcpath); INFO("Failed to open log file %s, log will be lost", lxcpath);
lxc_log_options_no_override(); lxc_log_options_no_override();
if (lxc_safe_int(argv[2], &pipefd) < 0) if (lxc_safe_int(argv[2], &pipefd) < 0)
...@@ -388,7 +396,7 @@ int main(int argc, char *argv[]) ...@@ -388,7 +396,7 @@ int main(int argc, char *argv[])
sigdelset(&mask, SIGBUS) || sigdelset(&mask, SIGBUS) ||
sigdelset(&mask, SIGTERM) || sigdelset(&mask, SIGTERM) ||
pthread_sigmask(SIG_BLOCK, &mask, NULL)) { pthread_sigmask(SIG_BLOCK, &mask, NULL)) {
SYSERROR("Failed to set signal mask."); SYSERROR("Failed to set signal mask");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
...@@ -401,10 +409,11 @@ int main(int argc, char *argv[]) ...@@ -401,10 +409,11 @@ int main(int argc, char *argv[])
goto on_signal; goto on_signal;
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
memset(&mon, 0, sizeof(mon)); memset(&mon, 0, sizeof(mon));
mon.lxcpath = lxcpath; mon.lxcpath = lxcpath;
if (lxc_mainloop_open(&mon.descr)) { if (lxc_mainloop_open(&mon.descr)) {
ERROR("Failed to create mainloop."); ERROR("Failed to create mainloop");
goto on_error; goto on_error;
} }
mainloop_opened = true; mainloop_opened = true;
...@@ -424,33 +433,38 @@ int main(int argc, char *argv[]) ...@@ -424,33 +433,38 @@ int main(int argc, char *argv[])
close(pipefd); close(pipefd);
if (lxc_monitord_mainloop_add(&mon)) { if (lxc_monitord_mainloop_add(&mon)) {
ERROR("Failed to add mainloop handlers."); ERROR("Failed to add mainloop handlers");
goto on_error; goto on_error;
} }
NOTICE("lxc-monitord with pid %d is now monitoring lxcpath %s.", NOTICE("lxc-monitord with pid %d is now monitoring lxcpath %s",
lxc_raw_getpid(), mon.lxcpath); lxc_raw_getpid(), mon.lxcpath);
for (;;) { for (;;) {
ret = lxc_mainloop(&mon.descr, 1000 * 30); ret = lxc_mainloop(&mon.descr, 1000 * 30);
if (ret) { if (ret) {
ERROR("mainloop returned an error"); ERROR("mainloop returned an error");
break; break;
} }
if (mon.clientfds_cnt <= 0) { if (mon.clientfds_cnt <= 0) {
NOTICE("No remaining clients. lxc-monitord is exiting."); NOTICE("No remaining clients. lxc-monitord is exiting");
break; break;
} }
if (quit == 1) {
NOTICE("got quit command. lxc-monitord is exitting."); if (quit == LXC_MAINLOOP_CLOSE) {
NOTICE("Got quit command. lxc-monitord is exitting");
break; break;
} }
} }
on_signal: on_signal:
ret = EXIT_SUCCESS; ret = EXIT_SUCCESS;
on_error: on_error:
if (monitord_created) if (monitord_created)
lxc_monitord_cleanup(); lxc_monitord_cleanup();
if (mainloop_opened) if (mainloop_opened)
lxc_mainloop_close(&mon.descr); lxc_mainloop_close(&mon.descr);
......
...@@ -240,18 +240,21 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd, ...@@ -240,18 +240,21 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
ret = lxc_abstract_unix_send_credential(client_fd, &cmd->req, ret = lxc_abstract_unix_send_credential(client_fd, &cmd->req,
sizeof(cmd->req)); sizeof(cmd->req));
if (ret < 0 || (size_t)ret != sizeof(cmd->req)) { if (ret < 0 ) {
close(client_fd); if (errno == EPIPE) {
close(client_fd);
if (errno == EPIPE)
return -EPIPE; return -EPIPE;
}
if (ret >= 0) close(client_fd);
return -EMSGSIZE;
return -1; return -1;
} }
if ((size_t)ret != sizeof(cmd->req)) {
close(client_fd);
return -EMSGSIZE;
}
if (cmd->req.datalen <= 0) if (cmd->req.datalen <= 0)
return client_fd; return client_fd;
...@@ -754,7 +757,7 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req, ...@@ -754,7 +757,7 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
rsp.data = INT_TO_PTR(ttynum); rsp.data = INT_TO_PTR(ttynum);
ret = lxc_abstract_unix_send_fds(fd, &masterfd, 1, &rsp, sizeof(rsp)); ret = lxc_abstract_unix_send_fds(fd, &masterfd, 1, &rsp, sizeof(rsp));
if (ret < 0) { if (ret < 0) {
ERROR("Failed to send tty to client"); SYSERROR("Failed to send tty to client");
lxc_terminal_free(handler->conf, fd); lxc_terminal_free(handler->conf, fd);
goto out_close; goto out_close;
} }
...@@ -1112,17 +1115,17 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data, ...@@ -1112,17 +1115,17 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
struct lxc_handler *handler = data; struct lxc_handler *handler = data;
ret = lxc_abstract_unix_rcv_credential(fd, &req, sizeof(req)); ret = lxc_abstract_unix_rcv_credential(fd, &req, sizeof(req));
if (ret == -EACCES) {
/* We don't care for the peer, just send and close. */
struct lxc_cmd_rsp rsp = {.ret = ret};
lxc_cmd_rsp_send(fd, &rsp);
goto out_close;
}
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to receive data on command socket for command " SYSERROR("Failed to receive data on command socket for command "
"\"%s\"", lxc_cmd_str(req.cmd)); "\"%s\"", lxc_cmd_str(req.cmd));
if (errno == EACCES) {
/* We don't care for the peer, just send and close. */
struct lxc_cmd_rsp rsp = {.ret = ret};
lxc_cmd_rsp_send(fd, &rsp);
}
goto out_close; goto out_close;
} }
......
...@@ -149,6 +149,7 @@ int parse_idmaps(const char *idmap, char *type, unsigned long *nsid, ...@@ -149,6 +149,7 @@ int parse_idmaps(const char *idmap, char *type, unsigned long *nsid,
*/ */
if (*(slide + strspn(slide, " \t\r\n")) != '\0') if (*(slide + strspn(slide, " \t\r\n")) != '\0')
goto on_error; goto on_error;
/* Mark end of range. */ /* Mark end of range. */
*slide = '\0'; *slide = '\0';
...@@ -211,6 +212,7 @@ struct lxc_netdev *lxc_network_add(struct lxc_list *networks, int idx, bool tail ...@@ -211,6 +212,7 @@ struct lxc_netdev *lxc_network_add(struct lxc_list *networks, int idx, bool tail
lxc_list_add_tail(networks, newlist); lxc_list_add_tail(networks, newlist);
else else
lxc_list_add(networks, newlist); lxc_list_add(networks, newlist);
return netdev; return netdev;
} }
...@@ -265,23 +267,29 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf) ...@@ -265,23 +267,29 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
TRACE("index: %zd", netdev->idx); TRACE("index: %zd", netdev->idx);
TRACE("ifindex: %d", netdev->ifindex); TRACE("ifindex: %d", netdev->ifindex);
switch (netdev->type) { switch (netdev->type) {
case LXC_NET_VETH: case LXC_NET_VETH:
TRACE("type: veth"); TRACE("type: veth");
if (netdev->priv.veth_attr.pair[0] != '\0') if (netdev->priv.veth_attr.pair[0] != '\0')
TRACE("veth pair: %s", TRACE("veth pair: %s",
netdev->priv.veth_attr.pair); netdev->priv.veth_attr.pair);
if (netdev->priv.veth_attr.veth1[0] != '\0') if (netdev->priv.veth_attr.veth1[0] != '\0')
TRACE("veth1 : %s", TRACE("veth1 : %s",
netdev->priv.veth_attr.veth1); netdev->priv.veth_attr.veth1);
if (netdev->priv.veth_attr.ifindex > 0) if (netdev->priv.veth_attr.ifindex > 0)
TRACE("host side ifindex for veth device: %d", TRACE("host side ifindex for veth device: %d",
netdev->priv.veth_attr.ifindex); netdev->priv.veth_attr.ifindex);
break; break;
case LXC_NET_MACVLAN: case LXC_NET_MACVLAN:
TRACE("type: macvlan"); TRACE("type: macvlan");
if (netdev->priv.macvlan_attr.mode > 0) { if (netdev->priv.macvlan_attr.mode > 0) {
char *macvlan_mode; char *macvlan_mode;
macvlan_mode = lxc_macvlan_flag_to_mode( macvlan_mode = lxc_macvlan_flag_to_mode(
netdev->priv.macvlan_attr.mode); netdev->priv.macvlan_attr.mode);
TRACE("macvlan mode: %s", TRACE("macvlan mode: %s",
...@@ -295,10 +303,10 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf) ...@@ -295,10 +303,10 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
break; break;
case LXC_NET_PHYS: case LXC_NET_PHYS:
TRACE("type: phys"); TRACE("type: phys");
if (netdev->priv.phys_attr.ifindex > 0) {
if (netdev->priv.phys_attr.ifindex > 0)
TRACE("host side ifindex for phys device: %d", TRACE("host side ifindex for phys device: %d",
netdev->priv.phys_attr.ifindex); netdev->priv.phys_attr.ifindex);
}
break; break;
case LXC_NET_EMPTY: case LXC_NET_EMPTY:
TRACE("type: empty"); TRACE("type: empty");
...@@ -314,16 +322,22 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf) ...@@ -314,16 +322,22 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
if (netdev->type != LXC_NET_EMPTY) { if (netdev->type != LXC_NET_EMPTY) {
TRACE("flags: %s", TRACE("flags: %s",
netdev->flags == IFF_UP ? "up" : "none"); netdev->flags == IFF_UP ? "up" : "none");
if (netdev->link[0] != '\0') if (netdev->link[0] != '\0')
TRACE("link: %s", netdev->link); TRACE("link: %s", netdev->link);
if (netdev->name[0] != '\0') if (netdev->name[0] != '\0')
TRACE("name: %s", netdev->name); TRACE("name: %s", netdev->name);
if (netdev->hwaddr) if (netdev->hwaddr)
TRACE("hwaddr: %s", netdev->hwaddr); TRACE("hwaddr: %s", netdev->hwaddr);
if (netdev->mtu) if (netdev->mtu)
TRACE("mtu: %s", netdev->mtu); TRACE("mtu: %s", netdev->mtu);
if (netdev->upscript) if (netdev->upscript)
TRACE("upscript: %s", netdev->upscript); TRACE("upscript: %s", netdev->upscript);
if (netdev->downscript) if (netdev->downscript)
TRACE("downscript: %s", netdev->downscript); TRACE("downscript: %s", netdev->downscript);
...@@ -345,11 +359,13 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf) ...@@ -345,11 +359,13 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
TRACE("ipv6 gateway auto: %s", TRACE("ipv6 gateway auto: %s",
netdev->ipv6_gateway_auto ? "true" : "false"); netdev->ipv6_gateway_auto ? "true" : "false");
if (netdev->ipv6_gateway) { if (netdev->ipv6_gateway) {
inet_ntop(AF_INET6, netdev->ipv6_gateway, inet_ntop(AF_INET6, netdev->ipv6_gateway,
bufinet6, sizeof(bufinet6)); bufinet6, sizeof(bufinet6));
TRACE("ipv6 gateway: %s", bufinet6); TRACE("ipv6 gateway: %s", bufinet6);
} }
lxc_list_for_each_safe(cur, &netdev->ipv6, next) { lxc_list_for_each_safe(cur, &netdev->ipv6, next) {
inet6dev = cur->elem; inet6dev = cur->elem;
inet_ntop(AF_INET6, &inet6dev->addr, bufinet6, inet_ntop(AF_INET6, &inet6dev->addr, bufinet6,
...@@ -477,7 +493,7 @@ int set_config_string_item(char **conf_item, const char *value) ...@@ -477,7 +493,7 @@ int set_config_string_item(char **conf_item, const char *value)
new_value = strdup(value); new_value = strdup(value);
if (!new_value) { if (!new_value) {
SYSERROR("failed to duplicate string \"%s\"", value); SYSERROR("Failed to duplicate string \"%s\"", value);
return -1; return -1;
} }
...@@ -505,8 +521,10 @@ int config_ip_prefix(struct in_addr *addr) ...@@ -505,8 +521,10 @@ int config_ip_prefix(struct in_addr *addr)
{ {
if (IN_CLASSA(addr->s_addr)) if (IN_CLASSA(addr->s_addr))
return 32 - IN_CLASSA_NSHIFT; return 32 - IN_CLASSA_NSHIFT;
if (IN_CLASSB(addr->s_addr)) if (IN_CLASSB(addr->s_addr))
return 32 - IN_CLASSB_NSHIFT; return 32 - IN_CLASSB_NSHIFT;
if (IN_CLASSC(addr->s_addr)) if (IN_CLASSC(addr->s_addr))
return 32 - IN_CLASSC_NSHIFT; return 32 - IN_CLASSC_NSHIFT;
...@@ -521,15 +539,14 @@ int network_ifname(char *valuep, const char *value, size_t size) ...@@ -521,15 +539,14 @@ int network_ifname(char *valuep, const char *value, size_t size)
return -1; return -1;
retlen = strlcpy(valuep, value, size); retlen = strlcpy(valuep, value, size);
if (retlen >= size) { if (retlen >= size)
ERROR("Network devie name \"%s\" is too long (>= %zu)", value, ERROR("Network devie name \"%s\" is too long (>= %zu)", value,
size); size);
}
return 0; return 0;
} }
int rand_complete_hwaddr(char *hwaddr) void rand_complete_hwaddr(char *hwaddr)
{ {
const char hex[] = "0123456789abcdef"; const char hex[] = "0123456789abcdef";
char *curs = hwaddr; char *curs = hwaddr;
...@@ -558,7 +575,6 @@ int rand_complete_hwaddr(char *hwaddr) ...@@ -558,7 +575,6 @@ int rand_complete_hwaddr(char *hwaddr)
} }
curs++; curs++;
} }
return 0;
} }
bool lxc_config_net_hwaddr(const char *line) bool lxc_config_net_hwaddr(const char *line)
...@@ -568,11 +584,15 @@ bool lxc_config_net_hwaddr(const char *line) ...@@ -568,11 +584,15 @@ bool lxc_config_net_hwaddr(const char *line)
if (strncmp(line, "lxc.net", 7) != 0) if (strncmp(line, "lxc.net", 7) != 0)
return false; return false;
if (strncmp(line, "lxc.net.hwaddr", 14) == 0) if (strncmp(line, "lxc.net.hwaddr", 14) == 0)
return true; return true;
if (strncmp(line, "lxc.network.hwaddr", 18) == 0) if (strncmp(line, "lxc.network.hwaddr", 18) == 0)
return true; return true;
if (sscanf(line, "lxc.net.%u.%6s", &index, tmp) == 2 || sscanf(line, "lxc.network.%u.%6s", &index, tmp) == 2)
if (sscanf(line, "lxc.net.%u.%6s", &index, tmp) == 2 ||
sscanf(line, "lxc.network.%u.%6s", &index, tmp) == 2)
return strncmp(tmp, "hwaddr", 6) == 0; return strncmp(tmp, "hwaddr", 6) == 0;
return false; return false;
...@@ -639,7 +659,7 @@ int lxc_get_conf_str(char *retv, int inlen, const char *value) ...@@ -639,7 +659,7 @@ int lxc_get_conf_str(char *retv, int inlen, const char *value)
if (retv && inlen >= value_len + 1) if (retv && inlen >= value_len + 1)
memcpy(retv, value, value_len + 1); memcpy(retv, value, value_len + 1);
return strlen(value); return value_len;
} }
int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v) int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v)
...@@ -701,6 +721,7 @@ bool parse_limit_value(const char **value, rlim_t *res) ...@@ -701,6 +721,7 @@ bool parse_limit_value(const char **value, rlim_t *res)
*res = strtoull(*value, &endptr, 10); *res = strtoull(*value, &endptr, 10);
if (errno || !endptr) if (errno || !endptr)
return false; return false;
*value = endptr; *value = endptr;
return true; return true;
...@@ -744,7 +765,7 @@ static int lxc_container_name_to_pid(const char *lxcname_or_pid, ...@@ -744,7 +765,7 @@ static int lxc_container_name_to_pid(const char *lxcname_or_pid,
ret = kill(pid, 0); ret = kill(pid, 0);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to send signal to pid %d", (int)pid); SYSERROR("Failed to send signal to pid %d", (int)pid);
return -EPERM; return -1;
} }
return pid; return pid;
...@@ -760,7 +781,7 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath, ...@@ -760,7 +781,7 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath,
if (lastslash) { if (lastslash) {
dup = strdup(lxcname_or_pid); dup = strdup(lxcname_or_pid);
if (!dup) if (!dup)
return -ENOMEM; return -1;
dup[lastslash - lxcname_or_pid] = '\0'; dup[lastslash - lxcname_or_pid] = '\0';
pid = lxc_container_name_to_pid(lastslash + 1, dup); pid = lxc_container_name_to_pid(lastslash + 1, dup);
...@@ -770,11 +791,11 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath, ...@@ -770,11 +791,11 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath,
} }
if (pid < 0) if (pid < 0)
return -EINVAL; return -1;
fd = lxc_preserve_ns(pid, namespace); fd = lxc_preserve_ns(pid, namespace);
if (fd < 0) if (fd < 0)
return -EINVAL; return -1;
return fd; return fd;
} }
...@@ -877,9 +898,8 @@ static int rt_sig_num(const char *signame) ...@@ -877,9 +898,8 @@ static int rt_sig_num(const char *signame)
{ {
int rtmax = 0, sig_n = 0; int rtmax = 0, sig_n = 0;
if (strncasecmp(signame, "max-", 4) == 0) { if (strncasecmp(signame, "max-", 4) == 0)
rtmax = 1; rtmax = 1;
}
signame += 4; signame += 4;
if (!isdigit(*signame)) if (!isdigit(*signame))
...@@ -903,10 +923,10 @@ int sig_parse(const char *signame) ...@@ -903,10 +923,10 @@ int sig_parse(const char *signame)
signame += 3; signame += 3;
if (strncasecmp(signame, "rt", 2) == 0) if (strncasecmp(signame, "rt", 2) == 0)
return rt_sig_num(signame + 2); return rt_sig_num(signame + 2);
for (n = 0; n < sizeof(signames) / sizeof((signames)[0]); n++) {
for (n = 0; n < sizeof(signames) / sizeof((signames)[0]); n++)
if (strcasecmp(signames[n].name, signame) == 0) if (strcasecmp(signames[n].name, signame) == 0)
return signames[n].num; return signames[n].num;
}
} }
return -1; return -1;
......
...@@ -81,7 +81,7 @@ extern int set_config_string_item_max(char **conf_item, const char *value, ...@@ -81,7 +81,7 @@ extern int set_config_string_item_max(char **conf_item, const char *value,
extern int set_config_path_item(char **conf_item, const char *value); extern int set_config_path_item(char **conf_item, const char *value);
extern int config_ip_prefix(struct in_addr *addr); extern int config_ip_prefix(struct in_addr *addr);
extern int network_ifname(char *valuep, const char *value, size_t size); extern int network_ifname(char *valuep, const char *value, size_t size);
extern int rand_complete_hwaddr(char *hwaddr); extern void rand_complete_hwaddr(char *hwaddr);
extern bool lxc_config_net_hwaddr(const char *line); extern bool lxc_config_net_hwaddr(const char *line);
extern void update_hwaddr(const char *line); extern void update_hwaddr(const char *line);
extern bool new_hwaddr(char *hwaddr); extern bool new_hwaddr(char *hwaddr);
......
...@@ -490,11 +490,17 @@ static int lxc_serve_state_socket_pair(const char *name, ...@@ -490,11 +490,17 @@ static int lxc_serve_state_socket_pair(const char *name,
again: again:
ret = lxc_abstract_unix_send_credential(handler->state_socket_pair[1], ret = lxc_abstract_unix_send_credential(handler->state_socket_pair[1],
&(int){state}, sizeof(int)); &(int){state}, sizeof(int));
if (ret != sizeof(int)) { if (ret < 0) {
SYSERROR("Failed to send state to %d", handler->state_socket_pair[1]);
if (errno == EINTR) if (errno == EINTR)
goto again; goto again;
SYSERROR("Failed to send state to %d",
handler->state_socket_pair[1]); return -1;
}
if (ret != sizeof(int)) {
ERROR("Message too long : %d", handler->state_socket_pair[1]);
return -1; return -1;
} }
...@@ -649,7 +655,7 @@ void lxc_free_handler(struct lxc_handler *handler) ...@@ -649,7 +655,7 @@ void lxc_free_handler(struct lxc_handler *handler)
if (handler->conf && handler->conf->reboot == REBOOT_NONE) if (handler->conf && handler->conf->reboot == REBOOT_NONE)
if (handler->conf->maincmd_fd >= 0) if (handler->conf->maincmd_fd >= 0)
close(handler->conf->maincmd_fd); lxc_abstract_unix_close(handler->conf->maincmd_fd);
if (handler->state_socket_pair[0] >= 0) if (handler->state_socket_pair[0] >= 0)
close(handler->state_socket_pair[0]); close(handler->state_socket_pair[0]);
...@@ -671,6 +677,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf, ...@@ -671,6 +677,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
handler = malloc(sizeof(*handler)); handler = malloc(sizeof(*handler));
if (!handler) if (!handler)
return NULL; return NULL;
memset(handler, 0, sizeof(*handler)); memset(handler, 0, sizeof(*handler));
/* Note that am_guest_unpriv() checks the effective uid. We /* Note that am_guest_unpriv() checks the effective uid. We
...@@ -704,6 +711,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf, ...@@ -704,6 +711,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
ERROR("Failed to create anonymous pair of unix sockets"); ERROR("Failed to create anonymous pair of unix sockets");
goto on_error; goto on_error;
} }
TRACE("Created anonymous pair {%d,%d} of unix sockets", TRACE("Created anonymous pair {%d,%d} of unix sockets",
handler->state_socket_pair[0], handler->state_socket_pair[0],
handler->state_socket_pair[1]); handler->state_socket_pair[1]);
...@@ -716,6 +724,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf, ...@@ -716,6 +724,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
goto on_error; goto on_error;
} }
} }
TRACE("Unix domain socket %d for command server is ready", TRACE("Unix domain socket %d for command server is ready",
handler->conf->maincmd_fd); handler->conf->maincmd_fd);
...@@ -866,7 +875,7 @@ out_delete_tty: ...@@ -866,7 +875,7 @@ out_delete_tty:
out_aborting: out_aborting:
(void)lxc_set_state(name, handler, ABORTING); (void)lxc_set_state(name, handler, ABORTING);
out_close_maincmd_fd: out_close_maincmd_fd:
close(conf->maincmd_fd); lxc_abstract_unix_close(conf->maincmd_fd);
conf->maincmd_fd = -1; conf->maincmd_fd = -1;
return -1; return -1;
} }
...@@ -953,7 +962,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler) ...@@ -953,7 +962,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
* the command socket causing a new process to get ECONNREFUSED * the command socket causing a new process to get ECONNREFUSED
* because we haven't yet closed the command socket. * because we haven't yet closed the command socket.
*/ */
close(handler->conf->maincmd_fd); lxc_abstract_unix_close(handler->conf->maincmd_fd);
handler->conf->maincmd_fd = -1; handler->conf->maincmd_fd = -1;
TRACE("Closed command socket"); TRACE("Closed command socket");
......
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