Module Name: src Committed By: elad Date: Tue Oct 6 04:28:11 UTC 2009
Modified Files: src/sys/kern: kern_verifiedexec.c vfs_subr.c src/sys/miscfs/specfs: spec_vnops.c specdev.h src/sys/secmodel/keylock: secmodel_keylock.c src/sys/secmodel/securelevel: secmodel_securelevel.c src/sys/sys: vnode.h Log Message: Factor out a block of code that appears in three places (Veriexec, keylock, and securelevel) so that others can use it as well. To generate a diff of this commit: cvs rdiff -u -r1.116 -r1.117 src/sys/kern/kern_verifiedexec.c cvs rdiff -u -r1.384 -r1.385 src/sys/kern/vfs_subr.c cvs rdiff -u -r1.125 -r1.126 src/sys/miscfs/specfs/spec_vnops.c cvs rdiff -u -r1.37 -r1.38 src/sys/miscfs/specfs/specdev.h cvs rdiff -u -r1.3 -r1.4 src/sys/secmodel/keylock/secmodel_keylock.c cvs rdiff -u -r1.16 -r1.17 \ src/sys/secmodel/securelevel/secmodel_securelevel.c cvs rdiff -u -r1.209 -r1.210 src/sys/sys/vnode.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_verifiedexec.c diff -u src/sys/kern/kern_verifiedexec.c:1.116 src/sys/kern/kern_verifiedexec.c:1.117 --- src/sys/kern/kern_verifiedexec.c:1.116 Sat Oct 3 21:03:55 2009 +++ src/sys/kern/kern_verifiedexec.c Tue Oct 6 04:28:10 2009 @@ -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 <e...@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 @@ 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 @@ 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) { Index: src/sys/kern/vfs_subr.c diff -u src/sys/kern/vfs_subr.c:1.384 src/sys/kern/vfs_subr.c:1.385 --- src/sys/kern/vfs_subr.c:1.384 Sat Sep 19 16:20:41 2009 +++ src/sys/kern/vfs_subr.c Tue Oct 6 04:28:10 2009 @@ -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 @@ } #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; +} Index: src/sys/miscfs/specfs/spec_vnops.c diff -u src/sys/miscfs/specfs/spec_vnops.c:1.125 src/sys/miscfs/specfs/spec_vnops.c:1.126 --- src/sys/miscfs/specfs/spec_vnops.c:1.125 Sun Oct 4 06:23:58 2009 +++ src/sys/miscfs/specfs/spec_vnops.c Tue Oct 6 04:28:10 2009 @@ -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_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. */ Index: src/sys/miscfs/specfs/specdev.h diff -u src/sys/miscfs/specfs/specdev.h:1.37 src/sys/miscfs/specfs/specdev.h:1.38 --- src/sys/miscfs/specfs/specdev.h:1.37 Mon Dec 29 17:41:19 2008 +++ src/sys/miscfs/specfs/specdev.h Tue Oct 6 04:28:11 2009 @@ -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 @@ #define spec_getpages genfs_getpages #define spec_putpages genfs_putpages +bool iskmemvp(struct vnode *); + #endif /* _MISCFS_SPECFS_SPECDEV_H_ */ Index: src/sys/secmodel/keylock/secmodel_keylock.c diff -u src/sys/secmodel/keylock/secmodel_keylock.c:1.3 src/sys/secmodel/keylock/secmodel_keylock.c:1.4 --- src/sys/secmodel/keylock/secmodel_keylock.c:1.3 Sat Oct 3 20:48:42 2009 +++ src/sys/secmodel/keylock/secmodel_keylock.c Tue Oct 6 04:28:10 2009 @@ -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 <m...@msys.ch> * Copyright (c) 2006 Elad Efrat <e...@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 @@ 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 @@ case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE: case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW: - 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; - } + error = rawdev_mounted(vp, NULL); - 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) Index: src/sys/secmodel/securelevel/secmodel_securelevel.c diff -u src/sys/secmodel/securelevel/secmodel_securelevel.c:1.16 src/sys/secmodel/securelevel/secmodel_securelevel.c:1.17 --- src/sys/secmodel/securelevel/secmodel_securelevel.c:1.16 Sat Oct 3 20:48:42 2009 +++ src/sys/secmodel/securelevel/secmodel_securelevel.c Tue Oct 6 04:28:10 2009 @@ -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 <e...@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 @@ 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 @@ case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW: if (securelevel > 0) result = KAUTH_RESULT_DENY; + break; default: @@ -518,57 +513,23 @@ 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; - - 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); + case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW: { + int error; - bvp = vp; + error = rawdev_mounted(vp, NULL); + /* Not a disk. */ + if (error == EINVAL) break; - } - default: - break; - } - - if (d_type != D_DISK) - 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; Index: src/sys/sys/vnode.h diff -u src/sys/sys/vnode.h:1.209 src/sys/sys/vnode.h:1.210 --- src/sys/sys/vnode.h:1.209 Sun Aug 16 10:51:21 2009 +++ src/sys/sys/vnode.h Tue Oct 6 04:28:10 2009 @@ -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 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 *);