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