Module Name:    src
Committed By:   elad
Date:           Sat Apr 25 18:53:45 UTC 2009

Modified Files:
        src/sys/fs/adosfs: advfsops.c
        src/sys/fs/cd9660: cd9660_vfsops.c
        src/sys/fs/efs: efs_vfsops.c
        src/sys/fs/filecorefs: filecore_vfsops.c
        src/sys/fs/hfs: hfs_vfsops.c
        src/sys/fs/msdosfs: msdosfs_vfsops.c
        src/sys/fs/sysvbfs: sysvbfs_vfsops.c
        src/sys/fs/udf: udf_vfsops.c
        src/sys/kern: vfs_subr.c
        src/sys/miscfs/genfs: genfs.h genfs_vnops.c
        src/sys/ufs/ext2fs: ext2fs_vfsops.c
        src/sys/ufs/ffs: ffs_vfsops.c

Log Message:
Add genfs_can_mount() and use it to prevent some more code duplication of
the security checks when mounting a device (VOP_ACCESS() + kauth(9) call)).

Proposed with no objections on tech-kern@:

        http://mail-index.netbsd.org/tech-kern/2009/04/20/msg004859.html

The vnode is always expected to be locked, so no locking is done outside
the file-system code.


To generate a diff of this commit:
cvs rdiff -u -r1.56 -r1.57 src/sys/fs/adosfs/advfsops.c
cvs rdiff -u -r1.65 -r1.66 src/sys/fs/cd9660/cd9660_vfsops.c
cvs rdiff -u -r1.18 -r1.19 src/sys/fs/efs/efs_vfsops.c
cvs rdiff -u -r1.58 -r1.59 src/sys/fs/filecorefs/filecore_vfsops.c
cvs rdiff -u -r1.20 -r1.21 src/sys/fs/hfs/hfs_vfsops.c
cvs rdiff -u -r1.73 -r1.74 src/sys/fs/msdosfs/msdosfs_vfsops.c
cvs rdiff -u -r1.28 -r1.29 src/sys/fs/sysvbfs/sysvbfs_vfsops.c
cvs rdiff -u -r1.55 -r1.56 src/sys/fs/udf/udf_vfsops.c
cvs rdiff -u -r1.374 -r1.375 src/sys/kern/vfs_subr.c
cvs rdiff -u -r1.24 -r1.25 src/sys/miscfs/genfs/genfs.h
cvs rdiff -u -r1.169 -r1.170 src/sys/miscfs/genfs/genfs_vnops.c
cvs rdiff -u -r1.142 -r1.143 src/sys/ufs/ext2fs/ext2fs_vfsops.c
cvs rdiff -u -r1.245 -r1.246 src/sys/ufs/ffs/ffs_vfsops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/fs/adosfs/advfsops.c
diff -u src/sys/fs/adosfs/advfsops.c:1.56 src/sys/fs/adosfs/advfsops.c:1.57
--- src/sys/fs/adosfs/advfsops.c:1.56	Sun Mar 15 17:15:57 2009
+++ src/sys/fs/adosfs/advfsops.c	Sat Apr 25 18:53:44 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: advfsops.c,v 1.56 2009/03/15 17:15:57 cegger Exp $	*/
+/*	$NetBSD: advfsops.c,v 1.57 2009/04/25 18:53:44 elad Exp $	*/
 
 /*
  * Copyright (c) 1994 Christian E. Hopps
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: advfsops.c,v 1.56 2009/03/15 17:15:57 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: advfsops.c,v 1.57 2009/04/25 18:53:44 elad Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -137,17 +137,15 @@
 	 * If mount by non-root, then verify that user has necessary
 	 * permissions on the device.
 	 */
-	if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL)) {
-		accessmode = VREAD;
-		if ((mp->mnt_flag & MNT_RDONLY) == 0)
-			accessmode |= VWRITE;
-		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-		error = VOP_ACCESS(devvp, accessmode, l->l_cred);
-		if (error) {
-			vput(devvp);
-			return (error);
-		}
-		VOP_UNLOCK(devvp, 0);
+	accessmode = VREAD;
+	if ((mp->mnt_flag & MNT_RDONLY) == 0)
+		accessmode |= VWRITE;
+	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+	error = genfs_can_mount(devvp, accessmode, l->l_cred);
+	VOP_UNLOCK(devvp, 0);
+	if (error) {
+		vrele(devvp);
+		return (error);
 	}
 /* MNT_UPDATE? */
 	if ((error = adosfs_mountfs(devvp, mp, l)) != 0) {

Index: src/sys/fs/cd9660/cd9660_vfsops.c
diff -u src/sys/fs/cd9660/cd9660_vfsops.c:1.65 src/sys/fs/cd9660/cd9660_vfsops.c:1.66
--- src/sys/fs/cd9660/cd9660_vfsops.c:1.65	Thu Jan 22 16:05:03 2009
+++ src/sys/fs/cd9660/cd9660_vfsops.c	Sat Apr 25 18:53:44 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: cd9660_vfsops.c,v 1.65 2009/01/22 16:05:03 cegger Exp $	*/
+/*	$NetBSD: cd9660_vfsops.c,v 1.66 2009/04/25 18:53:44 elad Exp $	*/
 
 /*-
  * Copyright (c) 1994
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cd9660_vfsops.c,v 1.65 2009/01/22 16:05:03 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cd9660_vfsops.c,v 1.66 2009/04/25 18:53:44 elad Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -264,14 +264,12 @@
 	 * If mount by non-root, then verify that user has necessary
 	 * permissions on the device.
 	 */
-	if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL) != 0) {
-		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-		error = VOP_ACCESS(devvp, VREAD, l->l_cred);
-		VOP_UNLOCK(devvp, 0);
-		if (error) {
-			vrele(devvp);
-			return (error);
-		}
+	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+	error = genfs_can_mount(devvp, VREAD, l->l_cred);
+	VOP_UNLOCK(devvp, 0);
+	if (error) {
+		vrele(devvp);
+		return (error);
 	}
 	if ((mp->mnt_flag & MNT_UPDATE) == 0) {
 		error = VOP_OPEN(devvp, FREAD, FSCRED);

Index: src/sys/fs/efs/efs_vfsops.c
diff -u src/sys/fs/efs/efs_vfsops.c:1.18 src/sys/fs/efs/efs_vfsops.c:1.19
--- src/sys/fs/efs/efs_vfsops.c:1.18	Mon Apr 20 21:29:01 2009
+++ src/sys/fs/efs/efs_vfsops.c	Sat Apr 25 18:53:44 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: efs_vfsops.c,v 1.18 2009/04/20 21:29:01 elad Exp $	*/
+/*	$NetBSD: efs_vfsops.c,v 1.19 2009/04/25 18:53:44 elad Exp $	*/
 
 /*
  * Copyright (c) 2006 Stephen M. Rumble <rum...@ephemeral.org>
@@ -17,7 +17,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: efs_vfsops.c,v 1.18 2009/04/20 21:29:01 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: efs_vfsops.c,v 1.19 2009/04/25 18:53:44 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -34,6 +34,7 @@
 #include <sys/module.h>
 
 #include <miscfs/genfs/genfs_node.h>
+#include <miscfs/genfs/genfs.h>
 
 #include <miscfs/specfs/specdev.h>
 
@@ -213,12 +214,10 @@
 	 * If mount by non-root, then verify that user has necessary
 	 * permissions on the device.
 	 */
-	if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL)) {
-		err = VOP_ACCESS(devvp, VREAD, l->l_cred);
-		if (err) {
-			vput(devvp);
-			return (err);
-		}
+	err = genfs_can_mount(devvp, VREAD, l->l_cred);
+	if (err) {
+		vput(devvp);
+		return (err);
 	}
 
 	if ((err = VOP_OPEN(devvp, mode, l->l_cred))) {

Index: src/sys/fs/filecorefs/filecore_vfsops.c
diff -u src/sys/fs/filecorefs/filecore_vfsops.c:1.58 src/sys/fs/filecorefs/filecore_vfsops.c:1.59
--- src/sys/fs/filecorefs/filecore_vfsops.c:1.58	Wed Mar 18 10:22:42 2009
+++ src/sys/fs/filecorefs/filecore_vfsops.c	Sat Apr 25 18:53:44 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: filecore_vfsops.c,v 1.58 2009/03/18 10:22:42 cegger Exp $	*/
+/*	$NetBSD: filecore_vfsops.c,v 1.59 2009/04/25 18:53:44 elad Exp $	*/
 
 /*-
  * Copyright (c) 1994 The Regents of the University of California.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: filecore_vfsops.c,v 1.58 2009/03/18 10:22:42 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: filecore_vfsops.c,v 1.59 2009/04/25 18:53:44 elad Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -288,14 +288,12 @@
 	 * If mount by non-root, then verify that user has necessary
 	 * permissions on the device.
 	 */
-	if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL)) {
-		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-		error = VOP_ACCESS(devvp, VREAD, l->l_cred);
-		VOP_UNLOCK(devvp, 0);
-		if (error) {
-			vrele(devvp);
-			return (error);
-		}
+	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+	error = genfs_can_mount(devvp, VREAD, l->l_cred);
+	VOP_UNLOCK(devvp, 0);
+	if (error) {
+		vrele(devvp);
+		return (error);
 	}
 	if ((mp->mnt_flag & MNT_UPDATE) == 0)
 		error = filecore_mountfs(devvp, mp, l, args);

Index: src/sys/fs/hfs/hfs_vfsops.c
diff -u src/sys/fs/hfs/hfs_vfsops.c:1.20 src/sys/fs/hfs/hfs_vfsops.c:1.21
--- src/sys/fs/hfs/hfs_vfsops.c:1.20	Wed Dec 17 20:51:35 2008
+++ src/sys/fs/hfs/hfs_vfsops.c	Sat Apr 25 18:53:44 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: hfs_vfsops.c,v 1.20 2008/12/17 20:51:35 cegger Exp $	*/
+/*	$NetBSD: hfs_vfsops.c,v 1.21 2009/04/25 18:53:44 elad Exp $	*/
 
 /*-
  * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc.
@@ -99,7 +99,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hfs_vfsops.c,v 1.20 2008/12/17 20:51:35 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hfs_vfsops.c,v 1.21 2009/04/25 18:53:44 elad Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -275,18 +275,19 @@
 	/*
 	 * If mount by non-root, then verify that user has necessary
 	 * permissions on the device.
+	 *
+	 * Permission to update a mount is checked higher, so here we presume
+	 * updating the mount is okay (for example, as far as securelevel goes)
+	 * which leaves us with the normal check.
 	 */
-	if (error == 0 && kauth_authorize_generic(l->l_cred,
-            KAUTH_GENERIC_ISSUSER, NULL) != 0) {
-		accessmode = VREAD;
-		if (update ?
-			(mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
-			(mp->mnt_flag & MNT_RDONLY) == 0)
-			accessmode |= VWRITE;
-		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-		error = VOP_ACCESS(devvp, accessmode, l->l_cred);
-		VOP_UNLOCK(devvp, 0);
-	}
+	accessmode = VREAD;
+	if (update ?
+		(mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
+		(mp->mnt_flag & MNT_RDONLY) == 0)
+		accessmode |= VWRITE;
+	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+	error = genfs_can_mount(devvp, accessmode, l->l_cred);
+	VOP_UNLOCK(devvp, 0);
 
 	if (error != 0)
 		goto error;

Index: src/sys/fs/msdosfs/msdosfs_vfsops.c
diff -u src/sys/fs/msdosfs/msdosfs_vfsops.c:1.73 src/sys/fs/msdosfs/msdosfs_vfsops.c:1.74
--- src/sys/fs/msdosfs/msdosfs_vfsops.c:1.73	Sun Mar 15 17:15:57 2009
+++ src/sys/fs/msdosfs/msdosfs_vfsops.c	Sat Apr 25 18:53:44 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: msdosfs_vfsops.c,v 1.73 2009/03/15 17:15:57 cegger Exp $	*/
+/*	$NetBSD: msdosfs_vfsops.c,v 1.74 2009/04/25 18:53:44 elad Exp $	*/
 
 /*-
  * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.73 2009/03/15 17:15:57 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.74 2009/04/25 18:53:44 elad Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -351,18 +351,20 @@
 			/*
 			 * If upgrade to read-write by non-root, then verify
 			 * that user has necessary permissions on the device.
+			 *
+			 * Permission to update a mount is checked higher, so here we presume
+			 * updating the mount is okay (for example, as far as securelevel goes)
+			 * which leaves us with the normal check.
 			 */
-			if (kauth_authorize_generic(l->l_cred,
-			    KAUTH_GENERIC_ISSUSER, NULL) != 0) {
-				devvp = pmp->pm_devvp;
-				vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-				error = VOP_ACCESS(devvp, VREAD | VWRITE,
-						   l->l_cred);
-				VOP_UNLOCK(devvp, 0);
-				DPRINTF(("VOP_ACCESS %d\n", error));
-				if (error)
-					return (error);
-			}
+			devvp = pmp->pm_devvp;
+			vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+			error = genfs_can_mount(devvp, VREAD | VWRITE,
+			    l->l_cred);
+			VOP_UNLOCK(devvp, 0);
+			DPRINTF(("genfs_can_mount %d\n", error));
+			if (error)
+				return (error);
+
 			pmp->pm_flags &= ~MSDOSFSMNT_RONLY;
 		}
 		if (args->fspec == NULL) {
@@ -395,18 +397,16 @@
 	 * If mount by non-root, then verify that user has necessary
 	 * permissions on the device.
 	 */
-	if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL) != 0) {
-		accessmode = VREAD;
-		if ((mp->mnt_flag & MNT_RDONLY) == 0)
-			accessmode |= VWRITE;
-		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-		error = VOP_ACCESS(devvp, accessmode, l->l_cred);
-		VOP_UNLOCK(devvp, 0);
-		if (error) {
-			DPRINTF(("VOP_ACCESS2 %d\n", error));
-			vrele(devvp);
-			return (error);
-		}
+	accessmode = VREAD;
+	if ((mp->mnt_flag & MNT_RDONLY) == 0)
+		accessmode |= VWRITE;
+	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+	error = genfs_can_mount(devvp, accessmode, l->l_cred);
+	VOP_UNLOCK(devvp, 0);
+	if (error) {
+		DPRINTF(("genfs_can_mount %d\n", error));
+		vrele(devvp);
+		return (error);
 	}
 	if ((mp->mnt_flag & MNT_UPDATE) == 0) {
 		int xflags;

Index: src/sys/fs/sysvbfs/sysvbfs_vfsops.c
diff -u src/sys/fs/sysvbfs/sysvbfs_vfsops.c:1.28 src/sys/fs/sysvbfs/sysvbfs_vfsops.c:1.29
--- src/sys/fs/sysvbfs/sysvbfs_vfsops.c:1.28	Thu Apr  9 09:56:30 2009
+++ src/sys/fs/sysvbfs/sysvbfs_vfsops.c	Sat Apr 25 18:53:44 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysvbfs_vfsops.c,v 1.28 2009/04/09 09:56:30 pooka Exp $	*/
+/*	$NetBSD: sysvbfs_vfsops.c,v 1.29 2009/04/25 18:53:44 elad Exp $	*/
 
 /*-
  * Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysvbfs_vfsops.c,v 1.28 2009/04/09 09:56:30 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysvbfs_vfsops.c,v 1.29 2009/04/25 18:53:44 elad Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -126,17 +126,19 @@
 	/*
 	 * If mount by non-root, then verify that user has necessary
 	 * permissions on the device.
+	 *
+	 * Permission to update a mount is checked higher, so here we presume
+	 * updating the mount is okay (for example, as far as securelevel goes)
+	 * which leaves us with the normal check.
 	 */
-	if (error == 0 && kauth_authorize_generic(l->l_cred,
-	    KAUTH_GENERIC_ISSUSER, NULL)) {
+	if (error == 0) {
 		int accessmode = VREAD;
 		if (update ?
 		    (mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
 		    (mp->mnt_flag & MNT_RDONLY) == 0)
 			accessmode |= VWRITE;
-		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-		error = VOP_ACCESS(devvp, accessmode, l->l_cred);
-		VOP_UNLOCK(devvp, 0);
+		
+		error = genfs_can_mount(devvp, accessmode, l->l_cred);
 	}
 
 	if (error) {

Index: src/sys/fs/udf/udf_vfsops.c
diff -u src/sys/fs/udf/udf_vfsops.c:1.55 src/sys/fs/udf/udf_vfsops.c:1.56
--- src/sys/fs/udf/udf_vfsops.c:1.55	Sun Feb  8 19:04:41 2009
+++ src/sys/fs/udf/udf_vfsops.c	Sat Apr 25 18:53:45 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_vfsops.c,v 1.55 2009/02/08 19:04:41 reinoud Exp $ */
+/* $NetBSD: udf_vfsops.c,v 1.56 2009/04/25 18:53:45 elad Exp $ */
 
 /*
  * Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: udf_vfsops.c,v 1.55 2009/02/08 19:04:41 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_vfsops.c,v 1.56 2009/04/25 18:53:45 elad Exp $");
 #endif /* not lint */
 
 
@@ -378,17 +378,15 @@
 	 * If mount by non-root, then verify that user has necessary
 	 * permissions on the device.
 	 */
-	if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL)) {
-		accessmode = VREAD;
-		if ((mp->mnt_flag & MNT_RDONLY) == 0)
-			accessmode |= VWRITE;
-		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-		error = VOP_ACCESS(devvp, accessmode, l->l_cred);
-		VOP_UNLOCK(devvp, 0);
-		if (error) {
-			vrele(devvp);
-			return error;
-		}
+	accessmode = VREAD;
+	if ((mp->mnt_flag & MNT_RDONLY) == 0)
+		accessmode |= VWRITE;
+	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+	error = genfs_can_mount(devvp, accessmode, l->l_cred);
+	VOP_UNLOCK(devvp, 0);
+	if (error) {
+		vrele(devvp);
+		return error;
 	}
 
 	/*

Index: src/sys/kern/vfs_subr.c
diff -u src/sys/kern/vfs_subr.c:1.374 src/sys/kern/vfs_subr.c:1.375
--- src/sys/kern/vfs_subr.c:1.374	Wed Apr 22 22:57:09 2009
+++ src/sys/kern/vfs_subr.c	Sat Apr 25 18:53:44 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_subr.c,v 1.374 2009/04/22 22:57:09 elad Exp $	*/
+/*	$NetBSD: vfs_subr.c,v 1.375 2009/04/25 18:53:44 elad Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc.
@@ -81,7 +81,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.374 2009/04/22 22:57:09 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.375 2009/04/25 18:53:44 elad Exp $");
 
 #include "opt_ddb.h"
 #include "opt_compat_netbsd.h"
@@ -2125,10 +2125,9 @@
 		}
 		savebp = bp;
 		/* Allocate a marker vnode. */
-		if ((mvp = vnalloc(mp)) == NULL) {
-			sysctl_relock();
-			return (ENOMEM);
-		}
+		mvp = vnalloc(mp);
+		/* Should never fail for mp != NULL */
+		KASSERT(mvp != NULL);
 		mutex_enter(&mntvnode_lock);
 		for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) {
 			vmark(mvp, vp);

Index: src/sys/miscfs/genfs/genfs.h
diff -u src/sys/miscfs/genfs/genfs.h:1.24 src/sys/miscfs/genfs/genfs.h:1.25
--- src/sys/miscfs/genfs/genfs.h:1.24	Wed Apr 22 22:57:08 2009
+++ src/sys/miscfs/genfs/genfs.h	Sat Apr 25 18:53:44 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: genfs.h,v 1.24 2009/04/22 22:57:08 elad Exp $	*/
+/*	$NetBSD: genfs.h,v 1.25 2009/04/25 18:53:44 elad Exp $	*/
 
 #ifndef	_MISCFS_GENFS_GENFS_H_
 #define	_MISCFS_GENFS_GENFS_H_
@@ -38,5 +38,6 @@
 
 int	genfs_can_chmod(vnode_t *, kauth_cred_t, uid_t, gid_t, mode_t);
 int	genfs_can_chown(vnode_t *, kauth_cred_t, uid_t, gid_t, uid_t, gid_t);
+int	genfs_can_mount(vnode_t *, mode_t, kauth_cred_t);
 
 #endif /* !_MISCFS_GENFS_GENFS_H_ */

Index: src/sys/miscfs/genfs/genfs_vnops.c
diff -u src/sys/miscfs/genfs/genfs_vnops.c:1.169 src/sys/miscfs/genfs/genfs_vnops.c:1.170
--- src/sys/miscfs/genfs/genfs_vnops.c:1.169	Wed Apr 22 22:57:08 2009
+++ src/sys/miscfs/genfs/genfs_vnops.c	Sat Apr 25 18:53:44 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: genfs_vnops.c,v 1.169 2009/04/22 22:57:08 elad Exp $	*/
+/*	$NetBSD: genfs_vnops.c,v 1.170 2009/04/25 18:53:44 elad Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.169 2009/04/22 22:57:08 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.170 2009/04/25 18:53:44 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -642,3 +642,26 @@
 	return (0);
 }
 
+/*
+ * Common routine to check if the device can be mounted.
+ *
+ * devvp - the locked vnode of the device
+ * cred - credentials of the invoker
+ * accessmode - the accessmode (VREAD, VWRITE)
+ *
+ * Returns 0 if the mount is allowed, or an error value otherwise.
+ */
+int
+genfs_can_mount(vnode_t *devvp, mode_t accessmode, kauth_cred_t cred)
+{
+	int error;
+
+	/* Always allow for root. */
+	error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL);
+	if (!error)
+		return (0);
+
+	error = VOP_ACCESS(devvp, accessmode, cred);
+
+	return (error);
+}

Index: src/sys/ufs/ext2fs/ext2fs_vfsops.c
diff -u src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.142 src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.143
--- src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.142	Sun Mar  1 15:59:57 2009
+++ src/sys/ufs/ext2fs/ext2fs_vfsops.c	Sat Apr 25 18:53:45 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ext2fs_vfsops.c,v 1.142 2009/03/01 15:59:57 christos Exp $	*/
+/*	$NetBSD: ext2fs_vfsops.c,v 1.143 2009/04/25 18:53:45 elad Exp $	*/
 
 /*
  * Copyright (c) 1989, 1991, 1993, 1994
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.142 2009/03/01 15:59:57 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.143 2009/04/25 18:53:45 elad Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -380,18 +380,19 @@
 	/*
 	 * If mount by non-root, then verify that user has necessary
 	 * permissions on the device.
+	 *
+	 * Permission to update a mount is checked higher, so here we presume
+	 * updating the mount is okay (for example, as far as securelevel goes)
+	 * which leaves us with the normal check.
 	 */
-	if (error == 0 && kauth_authorize_generic(l->l_cred,
-	    KAUTH_GENERIC_ISSUSER, NULL) != 0) {
-		accessmode = VREAD;
-		if (update ?
-		    (mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
-		    (mp->mnt_flag & MNT_RDONLY) == 0)
-			accessmode |= VWRITE;
-		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-		error = VOP_ACCESS(devvp, accessmode, l->l_cred);
-		VOP_UNLOCK(devvp, 0);
-	}
+	accessmode = VREAD;
+	if (update ?
+	    (mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
+	    (mp->mnt_flag & MNT_RDONLY) == 0)
+		accessmode |= VWRITE;
+	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+	error = genfs_can_mount(devvp, accessmode, l->l_cred);
+	VOP_UNLOCK(devvp, 0);
 
 	if (error) {
 		vrele(devvp);

Index: src/sys/ufs/ffs/ffs_vfsops.c
diff -u src/sys/ufs/ffs/ffs_vfsops.c:1.245 src/sys/ufs/ffs/ffs_vfsops.c:1.246
--- src/sys/ufs/ffs/ffs_vfsops.c:1.245	Sun Mar 29 10:29:00 2009
+++ src/sys/ufs/ffs/ffs_vfsops.c	Sat Apr 25 18:53:45 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ffs_vfsops.c,v 1.245 2009/03/29 10:29:00 ad Exp $	*/
+/*	$NetBSD: ffs_vfsops.c,v 1.246 2009/04/25 18:53:45 elad Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.245 2009/03/29 10:29:00 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.246 2009/04/25 18:53:45 elad Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ffs.h"
@@ -381,18 +381,19 @@
 	/*
 	 * If mount by non-root, then verify that user has necessary
 	 * permissions on the device.
-	 */
-	if (error == 0 && kauth_authorize_generic(l->l_cred,
-	    KAUTH_GENERIC_ISSUSER, NULL) != 0) {
-		accessmode = VREAD;
-		if (update ?
-		    (mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
-		    (mp->mnt_flag & MNT_RDONLY) == 0)
-			accessmode |= VWRITE;
-		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-		error = VOP_ACCESS(devvp, accessmode, l->l_cred);
-		VOP_UNLOCK(devvp, 0);
-	}
+	 *
+	 * Permission to update a mount is checked higher, so here we presume
+	 * updating the mount is okay (for example, as far as securelevel goes)
+	 * which leaves us with the normal check.
+	 */
+	accessmode = VREAD;
+	if (update ?
+	    (mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
+	    (mp->mnt_flag & MNT_RDONLY) == 0)
+		accessmode |= VWRITE;
+	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+	error = genfs_can_mount(devvp, accessmode, l->l_cred);
+	VOP_UNLOCK(devvp, 0);
 
 	if (error) {
 		vrele(devvp);

Reply via email to