Factor out a block of code that appears in three places (Veriexec, keylock,
and securelevel) so that others can use it as well.
This commit is contained in:
parent
b491010d02
commit
756638cf95
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kern_verifiedexec.c,v 1.116 2009/10/03 21:03:55 elad Exp $ */
|
||||
/* $NetBSD: kern_verifiedexec.c,v 1.117 2009/10/06 04:28:10 elad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005, 2006 Elad Efrat <elad@NetBSD.org>
|
||||
@ -29,7 +29,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.116 2009/10/03 21:03:55 elad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.117 2009/10/06 04:28:10 elad Exp $");
|
||||
|
||||
#include "opt_veriexec.h"
|
||||
|
||||
@ -1030,8 +1030,7 @@ veriexec_raw_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
|
||||
switch (action) {
|
||||
case KAUTH_DEVICE_RAWIO_SPEC: {
|
||||
struct vnode *vp, *bvp;
|
||||
dev_t dev;
|
||||
int d_type;
|
||||
int error;
|
||||
|
||||
if (req == KAUTH_REQ_DEVICE_RAWIO_SPEC_READ) {
|
||||
result = KAUTH_RESULT_DEFER;
|
||||
@ -1041,60 +1040,22 @@ veriexec_raw_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
|
||||
vp = arg1;
|
||||
KASSERT(vp != NULL);
|
||||
|
||||
dev = vp->v_rdev;
|
||||
d_type = D_OTHER;
|
||||
bvp = NULL;
|
||||
|
||||
/* Handle /dev/mem and /dev/kmem. */
|
||||
if ((vp->v_type == VCHR) && iskmemdev(dev)) {
|
||||
if (iskmemvp(vp)) {
|
||||
if (veriexec_strict < VERIEXEC_IPS)
|
||||
result = KAUTH_RESULT_DEFER;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
switch (vp->v_type) {
|
||||
case VCHR: {
|
||||
const struct cdevsw *cdev;
|
||||
|
||||
cdev = cdevsw_lookup(dev);
|
||||
if (cdev != NULL) {
|
||||
dev_t blkdev;
|
||||
|
||||
blkdev = devsw_chr2blk(dev);
|
||||
if (blkdev != NODEV) {
|
||||
vfinddev(blkdev, VBLK, &bvp);
|
||||
if (bvp != NULL)
|
||||
d_type = cdev->d_flag &
|
||||
D_TYPEMASK;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case VBLK: {
|
||||
const struct bdevsw *bdev;
|
||||
|
||||
bdev = bdevsw_lookup(dev);
|
||||
if (bdev != NULL)
|
||||
d_type = bdev->d_flag & D_TYPEMASK;
|
||||
|
||||
bvp = vp;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
result = KAUTH_RESULT_DEFER;
|
||||
break;
|
||||
}
|
||||
|
||||
if (d_type != D_DISK) {
|
||||
error = rawdev_mounted(vp, &bvp);
|
||||
if (error == EINVAL) {
|
||||
result = KAUTH_RESULT_DEFER;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: See vfs_mountedon() comment in secmodel/securelevel.
|
||||
* XXX: See vfs_mountedon() comment in rawdev_mounted().
|
||||
*/
|
||||
vte = veriexec_table_lookup(bvp->v_mount);
|
||||
if (vte == NULL) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vfs_subr.c,v 1.384 2009/09/19 16:20:41 jmcneill Exp $ */
|
||||
/* $NetBSD: vfs_subr.c,v 1.385 2009/10/06 04:28:10 elad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc.
|
||||
@ -91,7 +91,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.384 2009/09/19 16:20:41 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.385 2009/10/06 04:28:10 elad Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_compat_netbsd.h"
|
||||
@ -3289,3 +3289,76 @@ vfs_mount_print(struct mount *mp, int full, void (*pr)(const char *, ...))
|
||||
}
|
||||
#endif /* DDB || DEBUGPRINT */
|
||||
|
||||
/*
|
||||
* Check if a device pointed to by vp is mounted.
|
||||
*
|
||||
* Returns:
|
||||
* EINVAL if it's not a disk
|
||||
* EBUSY if it's a disk and mounted
|
||||
* 0 if it's a disk and not mounted
|
||||
*/
|
||||
int
|
||||
rawdev_mounted(struct vnode *vp, struct vnode **bvpp)
|
||||
{
|
||||
struct vnode *bvp;
|
||||
dev_t dev;
|
||||
int d_type;
|
||||
|
||||
bvp = NULL;
|
||||
dev = vp->v_rdev;
|
||||
d_type = D_OTHER;
|
||||
|
||||
if (iskmemvp(vp))
|
||||
return EINVAL;
|
||||
|
||||
switch (vp->v_type) {
|
||||
case VCHR: {
|
||||
const struct cdevsw *cdev;
|
||||
|
||||
cdev = cdevsw_lookup(dev);
|
||||
if (cdev != NULL) {
|
||||
dev_t blkdev;
|
||||
|
||||
blkdev = devsw_chr2blk(dev);
|
||||
if (blkdev != NODEV) {
|
||||
vfinddev(blkdev, VBLK, &bvp);
|
||||
if (bvp != NULL)
|
||||
d_type = (cdev->d_flag & D_TYPEMASK);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case VBLK: {
|
||||
const struct bdevsw *bdev;
|
||||
|
||||
bdev = bdevsw_lookup(dev);
|
||||
if (bdev != NULL)
|
||||
d_type = (bdev->d_flag & D_TYPEMASK);
|
||||
|
||||
bvp = vp;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (d_type != D_DISK)
|
||||
return EINVAL;
|
||||
|
||||
if (bvpp != NULL)
|
||||
*bvpp = bvp;
|
||||
|
||||
/*
|
||||
* XXX: This is bogus. We should be failing the request
|
||||
* XXX: not only if this specific slice is mounted, but
|
||||
* XXX: if it's on a disk with any other mounted slice.
|
||||
*/
|
||||
if (vfs_mountedon(bvp))
|
||||
return EBUSY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: spec_vnops.c,v 1.125 2009/10/04 06:23:58 tsutsui Exp $ */
|
||||
/* $NetBSD: spec_vnops.c,v 1.126 2009/10/06 04:28:10 elad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
@ -58,7 +58,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.125 2009/10/04 06:23:58 tsutsui Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.126 2009/10/06 04:28:10 elad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
@ -151,6 +151,13 @@ const struct vnodeopv_entry_desc spec_vnodeop_entries[] = {
|
||||
const struct vnodeopv_desc spec_vnodeop_opv_desc =
|
||||
{ &spec_vnodeop_p, spec_vnodeop_entries };
|
||||
|
||||
/* Returns true if vnode is /dev/mem or /dev/kmem. */
|
||||
bool
|
||||
iskmemvp(struct vnode *vp)
|
||||
{
|
||||
return ((vp->v_type == VCHR) && iskmemdev(vp->v_rdev));
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if dev is /dev/mem or /dev/kmem.
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: specdev.h,v 1.37 2008/12/29 17:41:19 pooka Exp $ */
|
||||
/* $NetBSD: specdev.h,v 1.38 2009/10/06 04:28:11 elad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
@ -155,4 +155,6 @@ int spec_advlock(void *);
|
||||
#define spec_getpages genfs_getpages
|
||||
#define spec_putpages genfs_putpages
|
||||
|
||||
bool iskmemvp(struct vnode *);
|
||||
|
||||
#endif /* _MISCFS_SPECFS_SPECDEV_H_ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: secmodel_keylock.c,v 1.3 2009/10/03 20:48:42 elad Exp $ */
|
||||
/* $NetBSD: secmodel_keylock.c,v 1.4 2009/10/06 04:28:10 elad Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2009 Marc Balmer <marc@msys.ch>
|
||||
* Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
|
||||
@ -54,7 +54,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: secmodel_keylock.c,v 1.3 2009/10/03 20:48:42 elad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: secmodel_keylock.c,v 1.4 2009/10/06 04:28:10 elad Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@ -421,22 +421,16 @@ secmodel_keylock_device_cb(kauth_cred_t cred,
|
||||
|
||||
switch (action) {
|
||||
case KAUTH_DEVICE_RAWIO_SPEC: {
|
||||
struct vnode *vp, *bvp;
|
||||
struct vnode *vp;
|
||||
enum kauth_device_req req;
|
||||
dev_t dev;
|
||||
int d_type;
|
||||
|
||||
req = (enum kauth_device_req)arg0;
|
||||
vp = arg1;
|
||||
|
||||
KASSERT(vp != NULL);
|
||||
|
||||
dev = vp->v_rdev;
|
||||
d_type = D_OTHER;
|
||||
bvp = NULL;
|
||||
|
||||
/* Handle /dev/mem and /dev/kmem. */
|
||||
if ((vp->v_type == VCHR) && iskmemdev(dev)) {
|
||||
if (iskmemvp(vp)) {
|
||||
switch (req) {
|
||||
case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ:
|
||||
break;
|
||||
@ -458,49 +452,12 @@ secmodel_keylock_device_cb(kauth_cred_t cred,
|
||||
|
||||
case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE:
|
||||
case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW:
|
||||
switch (vp->v_type) {
|
||||
case VCHR: {
|
||||
const struct cdevsw *cdev;
|
||||
error = rawdev_mounted(vp, NULL);
|
||||
|
||||
cdev = cdevsw_lookup(dev);
|
||||
if (cdev != NULL) {
|
||||
dev_t blkdev;
|
||||
|
||||
blkdev = devsw_chr2blk(dev);
|
||||
if (blkdev != NODEV) {
|
||||
vfinddev(blkdev, VBLK, &bvp);
|
||||
if (bvp != NULL)
|
||||
d_type = (cdev->d_flag
|
||||
& D_TYPEMASK);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case VBLK: {
|
||||
const struct bdevsw *bdev;
|
||||
|
||||
bdev = bdevsw_lookup(dev);
|
||||
if (bdev != NULL)
|
||||
d_type = (bdev->d_flag & D_TYPEMASK);
|
||||
|
||||
bvp = vp;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (d_type != D_DISK)
|
||||
if (error == EINVAL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* XXX: This is bogus. We should be failing the request
|
||||
* XXX: not only if this specific slice is mounted, but
|
||||
* XXX: if it's on a disk with any other mounted slice.
|
||||
*/
|
||||
if (vfs_mountedon(bvp) && (kstate != KEYLOCK_OPEN))
|
||||
if (error && (kstate != KEYLOCK_OPEN))
|
||||
break;
|
||||
|
||||
if (kstate == KEYLOCK_CLOSE)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: secmodel_securelevel.c,v 1.16 2009/10/03 20:48:42 elad Exp $ */
|
||||
/* $NetBSD: secmodel_securelevel.c,v 1.17 2009/10/06 04:28:10 elad Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
|
||||
* All rights reserved.
|
||||
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: secmodel_securelevel.c,v 1.16 2009/10/03 20:48:42 elad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: secmodel_securelevel.c,v 1.17 2009/10/06 04:28:10 elad Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_insecure.h"
|
||||
@ -480,22 +480,16 @@ secmodel_securelevel_device_cb(kauth_cred_t cred,
|
||||
|
||||
switch (action) {
|
||||
case KAUTH_DEVICE_RAWIO_SPEC: {
|
||||
struct vnode *vp, *bvp;
|
||||
struct vnode *vp;
|
||||
enum kauth_device_req req;
|
||||
dev_t dev;
|
||||
int d_type;
|
||||
|
||||
req = (enum kauth_device_req)arg0;
|
||||
vp = arg1;
|
||||
|
||||
KASSERT(vp != NULL);
|
||||
|
||||
dev = vp->v_rdev;
|
||||
d_type = D_OTHER;
|
||||
bvp = NULL;
|
||||
|
||||
/* Handle /dev/mem and /dev/kmem. */
|
||||
if ((vp->v_type == VCHR) && iskmemdev(dev)) {
|
||||
if (iskmemvp(vp)) {
|
||||
switch (req) {
|
||||
case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ:
|
||||
break;
|
||||
@ -504,6 +498,7 @@ secmodel_securelevel_device_cb(kauth_cred_t cred,
|
||||
case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW:
|
||||
if (securelevel > 0)
|
||||
result = KAUTH_RESULT_DENY;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -518,57 +513,23 @@ secmodel_securelevel_device_cb(kauth_cred_t cred,
|
||||
break;
|
||||
|
||||
case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE:
|
||||
case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW:
|
||||
switch (vp->v_type) {
|
||||
case VCHR: {
|
||||
const struct cdevsw *cdev;
|
||||
case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW: {
|
||||
int error;
|
||||
|
||||
cdev = cdevsw_lookup(dev);
|
||||
if (cdev != NULL) {
|
||||
dev_t blkdev;
|
||||
error = rawdev_mounted(vp, NULL);
|
||||
|
||||
blkdev = devsw_chr2blk(dev);
|
||||
if (blkdev != NODEV) {
|
||||
vfinddev(blkdev, VBLK, &bvp);
|
||||
if (bvp != NULL)
|
||||
d_type = (cdev->d_flag
|
||||
& D_TYPEMASK);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case VBLK: {
|
||||
const struct bdevsw *bdev;
|
||||
|
||||
bdev = bdevsw_lookup(dev);
|
||||
if (bdev != NULL)
|
||||
d_type = (bdev->d_flag & D_TYPEMASK);
|
||||
|
||||
bvp = vp;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (d_type != D_DISK)
|
||||
/* Not a disk. */
|
||||
if (error == EINVAL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* XXX: This is bogus. We should be failing the request
|
||||
* XXX: not only if this specific slice is mounted, but
|
||||
* XXX: if it's on a disk with any other mounted slice.
|
||||
*/
|
||||
if (vfs_mountedon(bvp) && (securelevel > 0))
|
||||
break;
|
||||
if (error && securelevel > 0)
|
||||
result = KAUTH_RESULT_DENY;
|
||||
|
||||
if (securelevel > 1)
|
||||
result = KAUTH_RESULT_DENY;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vnode.h,v 1.209 2009/08/16 10:51:21 yamt Exp $ */
|
||||
/* $NetBSD: vnode.h,v 1.210 2009/10/06 04:28:10 elad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
@ -658,6 +658,7 @@ int speedup_syncer(void);
|
||||
int dorevoke(struct vnode *, kauth_cred_t);
|
||||
int vlockmgr(struct vnlock *, int);
|
||||
int vlockstatus(struct vnlock *);
|
||||
int rawdev_mounted(struct vnode *, struct vnode **);
|
||||
|
||||
/* see vfssubr(9) */
|
||||
void vfs_getnewfsid(struct mount *);
|
||||
|
Loading…
Reference in New Issue
Block a user