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 *);

Reply via email to