Module Name: src
Committed By: maxv
Date: Wed Apr 10 18:49:04 UTC 2019
Modified Files:
src/lib/libnvmm: libnvmm.c nvmm.h
src/sys/dev/nvmm: nvmm.c nvmm_internal.h nvmm_ioctl.h
src/sys/secmodel/suser: secmodel_suser.c
src/sys/sys: kauth.h
Log Message:
Add the NVMM_CTL ioctl, always privileged regardless of the permissions of
/dev/nvmm. We'll use it to provide a way for an admin to control the
registered VMs in the kernel.
Add an associated wrapper in libnvmm.
To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/lib/libnvmm/libnvmm.c
cvs rdiff -u -r1.7 -r1.8 src/lib/libnvmm/nvmm.h
cvs rdiff -u -r1.16 -r1.17 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.8 -r1.9 src/sys/dev/nvmm/nvmm_internal.h
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/nvmm/nvmm_ioctl.h
cvs rdiff -u -r1.49 -r1.50 src/sys/secmodel/suser/secmodel_suser.c
cvs rdiff -u -r1.81 -r1.82 src/sys/sys/kauth.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libnvmm/libnvmm.c
diff -u src/lib/libnvmm/libnvmm.c:1.8 src/lib/libnvmm/libnvmm.c:1.9
--- src/lib/libnvmm/libnvmm.c:1.8 Thu Apr 4 17:33:47 2019
+++ src/lib/libnvmm/libnvmm.c Wed Apr 10 18:49:04 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: libnvmm.c,v 1.8 2019/04/04 17:33:47 maxv Exp $ */
+/* $NetBSD: libnvmm.c,v 1.9 2019/04/10 18:49:04 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -520,3 +520,24 @@ nvmm_callbacks_register(const struct nvm
{
memcpy(&__callbacks, cbs, sizeof(__callbacks));
}
+
+int
+nvmm_ctl(int op, void *data, size_t size)
+{
+ struct nvmm_ioc_ctl args;
+ int ret;
+
+ if (nvmm_init() == -1) {
+ return -1;
+ }
+
+ args.op = op;
+ args.data = data;
+ args.size = size;
+
+ ret = ioctl(nvmm_fd, NVMM_IOC_CTL, &args);
+ if (ret == -1)
+ return -1;
+
+ return 0;
+}
Index: src/lib/libnvmm/nvmm.h
diff -u src/lib/libnvmm/nvmm.h:1.7 src/lib/libnvmm/nvmm.h:1.8
--- src/lib/libnvmm/nvmm.h:1.7 Thu Apr 4 17:33:47 2019
+++ src/lib/libnvmm/nvmm.h Wed Apr 10 18:49:04 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm.h,v 1.7 2019/04/04 17:33:47 maxv Exp $ */
+/* $NetBSD: nvmm.h,v 1.8 2019/04/10 18:49:04 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -99,6 +99,8 @@ int nvmm_assist_io(struct nvmm_machine *
int nvmm_assist_mem(struct nvmm_machine *, nvmm_cpuid_t, struct nvmm_exit *);
void nvmm_callbacks_register(const struct nvmm_callbacks *);
+int nvmm_ctl(int, void *, size_t);
+
int nvmm_vcpu_dump(struct nvmm_machine *, nvmm_cpuid_t);
#endif /* _LIBNVMM_H_ */
Index: src/sys/dev/nvmm/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.16 src/sys/dev/nvmm/nvmm.c:1.17
--- src/sys/dev/nvmm/nvmm.c:1.16 Mon Apr 8 18:30:54 2019
+++ src/sys/dev/nvmm/nvmm.c Wed Apr 10 18:49:04 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm.c,v 1.16 2019/04/08 18:30:54 maxv Exp $ */
+/* $NetBSD: nvmm.c,v 1.17 2019/04/10 18:49:04 maxv Exp $ */
/*
* Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.16 2019/04/08 18:30:54 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.17 2019/04/10 18:49:04 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -44,6 +44,7 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.1
#include <sys/mman.h>
#include <sys/file.h>
#include <sys/filedesc.h>
+#include <sys/kauth.h>
#include <uvm/uvm.h>
#include <uvm/uvm_page.h>
@@ -64,6 +65,8 @@ static const struct nvmm_impl *nvmm_impl
static const struct nvmm_impl *nvmm_impl = NULL;
+static struct nvmm_owner root_owner;
+
/* -------------------------------------------------------------------------- */
static int
@@ -82,6 +85,7 @@ nvmm_machine_alloc(struct nvmm_machine *
}
mach->present = true;
+ mach->time = time_second;
*ret = mach;
atomic_inc_uint(&nmachines);
return 0;
@@ -116,7 +120,7 @@ nvmm_machine_get(struct nvmm_owner *owne
rw_exit(&mach->lock);
return ENOENT;
}
- if (mach->owner != owner) {
+ if (owner != &root_owner && mach->owner != owner) {
rw_exit(&mach->lock);
return EPERM;
}
@@ -816,6 +820,65 @@ out:
/* -------------------------------------------------------------------------- */
static int
+nvmm_ctl_mach_info(struct nvmm_ioc_ctl *args)
+{
+ struct nvmm_ctl_mach_info ctl;
+ struct nvmm_machine *mach;
+ struct nvmm_cpu *vcpu;
+ int error;
+ size_t i;
+
+ if (args->size != sizeof(ctl))
+ return EINVAL;
+ error = copyin(args->data, &ctl, sizeof(ctl));
+ if (error)
+ return error;
+
+ error = nvmm_machine_get(&root_owner, ctl.machid, &mach, true);
+ if (error)
+ return error;
+
+ ctl.nvcpus = 0;
+ for (i = 0; i < NVMM_MAX_VCPUS; i++) {
+ error = nvmm_vcpu_get(mach, i, &vcpu);
+ if (error)
+ continue;
+ ctl.nvcpus++;
+ nvmm_vcpu_put(vcpu);
+ }
+ ctl.pid = mach->owner->pid;
+ ctl.time = mach->time;
+
+ nvmm_machine_put(mach);
+
+ error = copyout(&ctl, args->data, sizeof(ctl));
+ if (error)
+ return error;
+
+ return 0;
+}
+
+static int
+nvmm_ctl(struct nvmm_owner *owner, struct nvmm_ioc_ctl *args)
+{
+ int error;
+
+ error = kauth_authorize_device(curlwp->l_cred, KAUTH_DEVICE_NVMM_CTL,
+ NULL, NULL, NULL, NULL);
+ if (error)
+ return error;
+
+ switch (args->op) {
+ case NVMM_CTL_MACH_INFO:
+ return nvmm_ctl_mach_info(args);
+ default:
+ return EINVAL;
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static int
nvmm_init(void)
{
size_t i, n;
@@ -965,6 +1028,8 @@ nvmm_ioctl(file_t *fp, u_long cmd, void
return nvmm_hva_map(owner, data);
case NVMM_IOC_HVA_UNMAP:
return nvmm_hva_unmap(owner, data);
+ case NVMM_IOC_CTL:
+ return nvmm_ctl(owner, data);
default:
return EINVAL;
}
Index: src/sys/dev/nvmm/nvmm_internal.h
diff -u src/sys/dev/nvmm/nvmm_internal.h:1.8 src/sys/dev/nvmm/nvmm_internal.h:1.9
--- src/sys/dev/nvmm/nvmm_internal.h:1.8 Mon Apr 8 18:21:42 2019
+++ src/sys/dev/nvmm/nvmm_internal.h Wed Apr 10 18:49:04 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm_internal.h,v 1.8 2019/04/08 18:21:42 maxv Exp $ */
+/* $NetBSD: nvmm_internal.h,v 1.9 2019/04/10 18:49:04 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -67,6 +67,7 @@ struct nvmm_hmapping {
struct nvmm_machine {
bool present;
nvmm_machid_t machid;
+ time_t time;
struct nvmm_owner *owner;
krwlock_t lock;
Index: src/sys/dev/nvmm/nvmm_ioctl.h
diff -u src/sys/dev/nvmm/nvmm_ioctl.h:1.4 src/sys/dev/nvmm/nvmm_ioctl.h:1.5
--- src/sys/dev/nvmm/nvmm_ioctl.h:1.4 Thu Mar 21 20:21:40 2019
+++ src/sys/dev/nvmm/nvmm_ioctl.h Wed Apr 10 18:49:04 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm_ioctl.h,v 1.4 2019/03/21 20:21:40 maxv Exp $ */
+/* $NetBSD: nvmm_ioctl.h,v 1.5 2019/04/10 18:49:04 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -118,6 +118,21 @@ struct nvmm_ioc_gpa_unmap {
size_t size;
};
+struct nvmm_ctl_mach_info {
+ nvmm_machid_t machid;
+ size_t nvcpus;
+ pid_t pid;
+ time_t time;
+};
+
+struct nvmm_ioc_ctl {
+ int op;
+#define NVMM_CTL_MACH_INFO 0
+
+ void *data;
+ size_t size;
+};
+
#define NVMM_IOC_CAPABILITY _IOR ('N', 0, struct nvmm_ioc_capability)
#define NVMM_IOC_MACHINE_CREATE _IOWR('N', 1, struct nvmm_ioc_machine_create)
#define NVMM_IOC_MACHINE_DESTROY _IOW ('N', 2, struct nvmm_ioc_machine_destroy)
@@ -133,4 +148,6 @@ struct nvmm_ioc_gpa_unmap {
#define NVMM_IOC_HVA_MAP _IOW ('N', 12, struct nvmm_ioc_hva_map)
#define NVMM_IOC_HVA_UNMAP _IOW ('N', 13, struct nvmm_ioc_hva_unmap)
+#define NVMM_IOC_CTL _IOW ('N', 20, struct nvmm_ioc_ctl)
+
#endif /* _NVMM_IOCTL_H_ */
Index: src/sys/secmodel/suser/secmodel_suser.c
diff -u src/sys/secmodel/suser/secmodel_suser.c:1.49 src/sys/secmodel/suser/secmodel_suser.c:1.50
--- src/sys/secmodel/suser/secmodel_suser.c:1.49 Fri Oct 5 22:12:38 2018
+++ src/sys/secmodel/suser/secmodel_suser.c Wed Apr 10 18:49:04 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: secmodel_suser.c,v 1.49 2018/10/05 22:12:38 christos Exp $ */
+/* $NetBSD: secmodel_suser.c,v 1.50 2019/04/10 18:49:04 maxv Exp $ */
/*-
* Copyright (c) 2006 Elad Efrat <[email protected]>
* All rights reserved.
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.49 2018/10/05 22:12:38 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.50 2019/04/10 18:49:04 maxv Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -893,6 +893,7 @@ secmodel_suser_device_cb(kauth_cred_t cr
case KAUTH_DEVICE_RND_SETPRIV:
case KAUTH_DEVICE_WSCONS_KEYBOARD_BELL:
case KAUTH_DEVICE_WSCONS_KEYBOARD_KEYREPEAT:
+ case KAUTH_DEVICE_NVMM_CTL:
if (isroot)
result = KAUTH_RESULT_ALLOW;
break;
Index: src/sys/sys/kauth.h
diff -u src/sys/sys/kauth.h:1.81 src/sys/sys/kauth.h:1.82
--- src/sys/sys/kauth.h:1.81 Fri Oct 5 22:12:37 2018
+++ src/sys/sys/kauth.h Wed Apr 10 18:49:04 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: kauth.h,v 1.81 2018/10/05 22:12:37 christos Exp $ */
+/* $NetBSD: kauth.h,v 1.82 2019/04/10 18:49:04 maxv Exp $ */
/*-
* Copyright (c) 2005, 2006 Elad Efrat <[email protected]>
@@ -347,6 +347,7 @@ enum {
KAUTH_DEVICE_TTY_VIRTUAL,
KAUTH_DEVICE_WSCONS_KEYBOARD_BELL,
KAUTH_DEVICE_WSCONS_KEYBOARD_KEYREPEAT,
+ KAUTH_DEVICE_NVMM_CTL,
};
/*