Module Name: src Committed By: maxv Date: Sun Oct 27 20:17:36 UTC 2019
Modified Files: src/lib/libnvmm: libnvmm.c nvmm.h src/sys/dev/nvmm: nvmm.c Log Message: Change the way root_owner works: consider the calling process as root_owner not if it has root privileges, but if the /dev/nvmm device was opened with write permissions. Introduce the undocumented nvmm_root_init() function to achieve that. The goal is to simplify the logic and have more granularity, eg if we want a monitoring agent to access VMs but don't want to give this agent real root access on the system. To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 src/lib/libnvmm/libnvmm.c cvs rdiff -u -r1.15 -r1.16 src/lib/libnvmm/nvmm.h cvs rdiff -u -r1.23 -r1.24 src/sys/dev/nvmm/nvmm.c 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.17 src/lib/libnvmm/libnvmm.c:1.18 --- src/lib/libnvmm/libnvmm.c:1.17 Sun Oct 27 07:08:15 2019 +++ src/lib/libnvmm/libnvmm.c Sun Oct 27 20:17:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: libnvmm.c,v 1.17 2019/10/27 07:08:15 maxv Exp $ */ +/* $NetBSD: libnvmm.c,v 1.18 2019/10/27 20:17:36 maxv Exp $ */ /* * Copyright (c) 2018-2019 The NetBSD Foundation, Inc. @@ -180,6 +180,29 @@ nvmm_init(void) } int +nvmm_root_init(void) +{ + if (nvmm_fd != -1) + return 0; + nvmm_fd = open("/dev/nvmm", O_WRONLY | O_CLOEXEC); + if (nvmm_fd == -1) + return -1; + if (nvmm_capability(&__capability) == -1) { + close(nvmm_fd); + nvmm_fd = -1; + return -1; + } + if (__capability.version != NVMM_KERN_VERSION) { + close(nvmm_fd); + nvmm_fd = -1; + errno = EPROGMISMATCH; + return -1; + } + + return 0; +} + +int nvmm_capability(struct nvmm_capability *cap) { struct nvmm_ioc_capability args; Index: src/lib/libnvmm/nvmm.h diff -u src/lib/libnvmm/nvmm.h:1.15 src/lib/libnvmm/nvmm.h:1.16 --- src/lib/libnvmm/nvmm.h:1.15 Sun Oct 27 07:08:15 2019 +++ src/lib/libnvmm/nvmm.h Sun Oct 27 20:17:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm.h,v 1.15 2019/10/27 07:08:15 maxv Exp $ */ +/* $NetBSD: nvmm.h,v 1.16 2019/10/27 20:17:36 maxv Exp $ */ /* * Copyright (c) 2018-2019 The NetBSD Foundation, Inc. @@ -90,6 +90,7 @@ struct nvmm_mem { typedef uint64_t nvmm_prot_t; int nvmm_init(void); +int nvmm_root_init(void); int nvmm_capability(struct nvmm_capability *); Index: src/sys/dev/nvmm/nvmm.c diff -u src/sys/dev/nvmm/nvmm.c:1.23 src/sys/dev/nvmm/nvmm.c:1.24 --- src/sys/dev/nvmm/nvmm.c:1.23 Wed Oct 23 07:01:11 2019 +++ src/sys/dev/nvmm/nvmm.c Sun Oct 27 20:17:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm.c,v 1.23 2019/10/23 07:01:11 maxv Exp $ */ +/* $NetBSD: nvmm.c,v 1.24 2019/10/27 20:17:36 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.23 2019/10/23 07:01:11 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.24 2019/10/27 20:17:36 maxv Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -889,7 +889,7 @@ out: /* -------------------------------------------------------------------------- */ static int -nvmm_ctl_mach_info(struct nvmm_ioc_ctl *args) +nvmm_ctl_mach_info(struct nvmm_owner *owner, struct nvmm_ioc_ctl *args) { struct nvmm_ctl_mach_info ctl; struct nvmm_machine *mach; @@ -903,7 +903,7 @@ nvmm_ctl_mach_info(struct nvmm_ioc_ctl * if (error) return error; - error = nvmm_machine_get(&root_owner, ctl.machid, &mach, true); + error = nvmm_machine_get(owner, ctl.machid, &mach, true); if (error) return error; @@ -930,16 +930,9 @@ nvmm_ctl_mach_info(struct nvmm_ioc_ctl * 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); + return nvmm_ctl_mach_info(owner, args); default: return EINVAL; } @@ -1047,8 +1040,12 @@ nvmm_open(dev_t dev, int flags, int type if (error) return error; - owner = kmem_alloc(sizeof(*owner), KM_SLEEP); - owner->pid = l->l_proc->p_pid; + if (OFLAGS(flags) & O_WRONLY) { + owner = &root_owner; + } else { + owner = kmem_alloc(sizeof(*owner), KM_SLEEP); + owner->pid = l->l_proc->p_pid; + } return fd_clone(fp, fd, flags, &nvmm_fileops, owner); } @@ -1060,7 +1057,9 @@ nvmm_close(file_t *fp) KASSERT(owner != NULL); nvmm_kill_machines(owner); - kmem_free(owner, sizeof(*owner)); + if (owner != &root_owner) { + kmem_free(owner, sizeof(*owner)); + } fp->f_data = NULL; return 0;