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 <e...@netbsd.org>
  * 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 <e...@netbsd.org>  
@@ -347,6 +347,7 @@ enum {
 	KAUTH_DEVICE_TTY_VIRTUAL,
 	KAUTH_DEVICE_WSCONS_KEYBOARD_BELL,
 	KAUTH_DEVICE_WSCONS_KEYBOARD_KEYREPEAT,
+	KAUTH_DEVICE_NVMM_CTL,
 };
 
 /*

Reply via email to