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.
This commit is contained in:
parent
2845a430aa
commit
d2ac291e7d
@ -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.
|
* Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
|
||||||
@ -179,6 +179,29 @@ nvmm_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
int
|
||||||
nvmm_capability(struct nvmm_capability *cap)
|
nvmm_capability(struct nvmm_capability *cap)
|
||||||
{
|
{
|
||||||
|
@ -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.
|
* Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
|
||||||
@ -90,6 +90,7 @@ struct nvmm_mem {
|
|||||||
typedef uint64_t nvmm_prot_t;
|
typedef uint64_t nvmm_prot_t;
|
||||||
|
|
||||||
int nvmm_init(void);
|
int nvmm_init(void);
|
||||||
|
int nvmm_root_init(void);
|
||||||
|
|
||||||
int nvmm_capability(struct nvmm_capability *);
|
int nvmm_capability(struct nvmm_capability *);
|
||||||
|
|
||||||
|
@ -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.
|
* Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
|
||||||
@ -30,7 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
@ -889,7 +889,7 @@ out:
|
|||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int
|
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_ctl_mach_info ctl;
|
||||||
struct nvmm_machine *mach;
|
struct nvmm_machine *mach;
|
||||||
@ -903,7 +903,7 @@ nvmm_ctl_mach_info(struct nvmm_ioc_ctl *args)
|
|||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
error = nvmm_machine_get(&root_owner, ctl.machid, &mach, true);
|
error = nvmm_machine_get(owner, ctl.machid, &mach, true);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@ -930,16 +930,9 @@ nvmm_ctl_mach_info(struct nvmm_ioc_ctl *args)
|
|||||||
static int
|
static int
|
||||||
nvmm_ctl(struct nvmm_owner *owner, struct nvmm_ioc_ctl *args)
|
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) {
|
switch (args->op) {
|
||||||
case NVMM_CTL_MACH_INFO:
|
case NVMM_CTL_MACH_INFO:
|
||||||
return nvmm_ctl_mach_info(args);
|
return nvmm_ctl_mach_info(owner, args);
|
||||||
default:
|
default:
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@ -1047,8 +1040,12 @@ nvmm_open(dev_t dev, int flags, int type, struct lwp *l)
|
|||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
owner = kmem_alloc(sizeof(*owner), KM_SLEEP);
|
if (OFLAGS(flags) & O_WRONLY) {
|
||||||
owner->pid = l->l_proc->p_pid;
|
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);
|
return fd_clone(fp, fd, flags, &nvmm_fileops, owner);
|
||||||
}
|
}
|
||||||
@ -1060,7 +1057,9 @@ nvmm_close(file_t *fp)
|
|||||||
|
|
||||||
KASSERT(owner != NULL);
|
KASSERT(owner != NULL);
|
||||||
nvmm_kill_machines(owner);
|
nvmm_kill_machines(owner);
|
||||||
kmem_free(owner, sizeof(*owner));
|
if (owner != &root_owner) {
|
||||||
|
kmem_free(owner, sizeof(*owner));
|
||||||
|
}
|
||||||
fp->f_data = NULL;
|
fp->f_data = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user