summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/vmd/control.c41
-rw-r--r--usr.sbin/vmd/proc.h4
-rw-r--r--usr.sbin/vmmctl/main.c14
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: