diff options
-rw-r--r-- | usr.sbin/vmd/control.c | 41 | ||||
-rw-r--r-- | usr.sbin/vmd/proc.h | 4 | ||||
-rw-r--r-- | usr.sbin/vmmctl/main.c | 14 |
3 files changed, 52 insertions, 7 deletions
diff --git a/usr.sbin/vmd/control.c b/usr.sbin/vmd/control.c index 65b7b134bec..4bba8935023 100644 --- a/usr.sbin/vmd/control.c +++ b/usr.sbin/vmd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.2 2015/12/02 22:19:11 reyk Exp $ */ +/* $OpenBSD: control.c,v 1.3 2015/12/03 13:08:44 reyk Exp $ */ /* * Copyright (c) 2010-2015 Reyk Floeter <reyk@openbsd.org> @@ -223,6 +223,14 @@ control_accept(int listenfd, short event, void *arg) return; } + if (getsockopt(connfd, SOL_SOCKET, SO_PEERCRED, + &c->peercred, &len) != 0) { + log_warn("%s: failed to get peer credentials", __func__); + close(connfd); + free(c); + return; + } + imsg_init(&c->iev.ibuf, connfd); c->iev.handler = control_dispatch_imsg; c->iev.events = EV_READ; @@ -279,7 +287,7 @@ control_dispatch_imsg(int fd, short event, void *arg) struct privsep *ps = cs->cs_env; struct ctl_conn *c; struct imsg imsg; - int n, v; + int n, v, ret = 0; if ((c = control_connbyfd(fd)) == NULL) { log_warn("%s: fd %d: not found", __func__, fd); @@ -308,6 +316,23 @@ control_dispatch_imsg(int fd, short event, void *arg) if (n == 0) break; + switch (imsg.hdr.type) { + case IMSG_CTL_NOTIFY: + case IMSG_CTL_VERBOSE: + case IMSG_VMDOP_START_VM_REQUEST: + case IMSG_VMDOP_TERMINATE_VM_REQUEST: + if (c->peercred.uid != 0) { + log_warnx("denied request %d from uid %d", + imsg.hdr.type, c->peercred.uid); + ret = EPERM; + goto fail; + } + break; + case IMSG_VMDOP_GET_INFO_VM_REQUEST: + default: + break; + } + control_imsg_forward(&imsg); switch (imsg.hdr.type) { @@ -316,9 +341,8 @@ control_dispatch_imsg(int fd, short event, void *arg) log_debug("%s: " "client requested notify more than once", __func__); - imsg_compose_event(&c->iev, IMSG_CTL_FAIL, - 0, 0, -1, NULL, 0); - break; + ret = EINVAL; + goto fail; } c->flags |= CTL_CONN_NOTIFY; break; @@ -352,6 +376,13 @@ control_dispatch_imsg(int fd, short event, void *arg) } imsg_event_add(&c->iev); + return; + + fail: + imsg_compose_event(&c->iev, IMSG_CTL_FAIL, + 0, 0, -1, &ret, sizeof(ret)); + imsg_flush(&c->iev.ibuf); + control_close(fd, cs); } void diff --git a/usr.sbin/vmd/proc.h b/usr.sbin/vmd/proc.h index b9228afed36..59ac73b1f1d 100644 --- a/usr.sbin/vmd/proc.h +++ b/usr.sbin/vmd/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.5 2015/12/03 08:42:11 reyk Exp $ */ +/* $OpenBSD: proc.h,v 1.6 2015/12/03 13:08:44 reyk Exp $ */ /* * Copyright (c) 2010-2015 Reyk Floeter <reyk@openbsd.org> @@ -16,6 +16,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <sys/socket.h> #include <sys/queue.h> #include <sys/uio.h> @@ -76,6 +77,7 @@ struct ctl_conn { unsigned int waiting; #define CTL_CONN_NOTIFY 0x01 struct imsgev iev; + struct sockpeercred peercred; }; TAILQ_HEAD(ctl_connlist, ctl_conn); diff --git a/usr.sbin/vmmctl/main.c b/usr.sbin/vmmctl/main.c index e13162ed6ca..8979f17bfe3 100644 --- a/usr.sbin/vmmctl/main.c +++ b/usr.sbin/vmmctl/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.6 2015/12/02 09:14:25 reyk Exp $ */ +/* $OpenBSD: main.c,v 1.7 2015/12/03 13:08:44 reyk Exp $ */ /* * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org> @@ -236,6 +236,18 @@ vmmaction(struct parse_result *res) if (n == 0) break; + if (imsg.hdr.type == IMSG_CTL_FAIL) { + if (IMSG_DATA_SIZE(&imsg) == sizeof(ret)) { + memcpy(&ret, imsg.data, sizeof(ret)); + errno = ret; + warn("command failed"); + } else { + warnx("command failed"); + } + done = 1; + break; + } + ret = 0; switch (res->action) { case CMD_START: |