tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: More duplicate code, vnode locking question



Attached is the diff implementing the changes as discussed:

  - genfs_can_mount(devvp, mode, cred) is added to genfs_vnops.c

  - devvp is expected to be locked

Please review. :)

Thanks,

-e.
Index: sys/miscfs/genfs/genfs.h
===================================================================
RCS file: /cvsroot/src/sys/miscfs/genfs/genfs.h,v
retrieving revision 1.24
diff -u -p -r1.24 genfs.h
--- sys/miscfs/genfs/genfs.h    22 Apr 2009 22:57:08 -0000      1.24
+++ sys/miscfs/genfs/genfs.h    22 Apr 2009 23:54:20 -0000
@@ -38,5 +38,6 @@ void  genfs_renamelock_exit(struct mount 
 
 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: sys/miscfs/genfs/genfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/genfs/genfs_vnops.c,v
retrieving revision 1.169
diff -u -p -r1.169 genfs_vnops.c
--- sys/miscfs/genfs/genfs_vnops.c      22 Apr 2009 22:57:08 -0000      1.169
+++ sys/miscfs/genfs/genfs_vnops.c      22 Apr 2009 23:54:20 -0000
@@ -642,3 +642,26 @@ genfs_can_chown(vnode_t *vp, kauth_cred_
        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: sys/fs/adosfs/advfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/adosfs/advfsops.c,v
retrieving revision 1.56
diff -u -p -r1.56 advfsops.c
--- sys/fs/adosfs/advfsops.c    15 Mar 2009 17:15:57 -0000      1.56
+++ sys/fs/adosfs/advfsops.c    22 Apr 2009 23:54:20 -0000
@@ -137,17 +137,15 @@ adosfs_mount(struct mount *mp, const cha
         * 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: sys/fs/cd9660/cd9660_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/cd9660/cd9660_vfsops.c,v
retrieving revision 1.65
diff -u -p -r1.65 cd9660_vfsops.c
--- sys/fs/cd9660/cd9660_vfsops.c       22 Jan 2009 16:05:03 -0000      1.65
+++ sys/fs/cd9660/cd9660_vfsops.c       22 Apr 2009 23:54:21 -0000
@@ -264,14 +264,12 @@ cd9660_mount(struct mount *mp, const cha
         * 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: sys/fs/filecorefs/filecore_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/filecorefs/filecore_vfsops.c,v
retrieving revision 1.58
diff -u -p -r1.58 filecore_vfsops.c
--- sys/fs/filecorefs/filecore_vfsops.c 18 Mar 2009 10:22:42 -0000      1.58
+++ sys/fs/filecorefs/filecore_vfsops.c 22 Apr 2009 23:54:21 -0000
@@ -288,14 +288,12 @@ filecore_mount(struct mount *mp, const c
         * 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: sys/fs/msdosfs/msdosfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/msdosfs/msdosfs_vfsops.c,v
retrieving revision 1.73
diff -u -p -r1.73 msdosfs_vfsops.c
--- sys/fs/msdosfs/msdosfs_vfsops.c     15 Mar 2009 17:15:57 -0000      1.73
+++ sys/fs/msdosfs/msdosfs_vfsops.c     22 Apr 2009 23:54:21 -0000
@@ -351,18 +351,20 @@ msdosfs_mount(struct mount *mp, const ch
                        /*
                         * 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 @@ msdosfs_mount(struct mount *mp, const ch
         * 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: sys/fs/sysvbfs/sysvbfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/sysvbfs/sysvbfs_vfsops.c,v
retrieving revision 1.26
diff -u -p -r1.26 sysvbfs_vfsops.c
--- sys/fs/sysvbfs/sysvbfs_vfsops.c     4 Sep 2008 12:28:14 -0000       1.26
+++ sys/fs/sysvbfs/sysvbfs_vfsops.c     22 Apr 2009 23:54:21 -0000
@@ -126,17 +126,19 @@ sysvbfs_mount(struct mount *mp, const ch
        /*
         * 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: sys/fs/efs/efs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/efs/efs_vfsops.c,v
retrieving revision 1.18
diff -u -p -r1.18 efs_vfsops.c
--- sys/fs/efs/efs_vfsops.c     20 Apr 2009 21:29:01 -0000      1.18
+++ sys/fs/efs/efs_vfsops.c     22 Apr 2009 23:54:22 -0000
@@ -34,6 +34,7 @@ __KERNEL_RCSID(0, "$NetBSD: efs_vfsops.c
 #include <sys/module.h>
 
 #include <miscfs/genfs/genfs_node.h>
+#include <miscfs/genfs/genfs.h>
 
 #include <miscfs/specfs/specdev.h>
 
@@ -213,12 +214,10 @@ efs_mount(struct mount *mp, const char *
         * 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: sys/fs/hfs/hfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/hfs/hfs_vfsops.c,v
retrieving revision 1.20
diff -u -p -r1.20 hfs_vfsops.c
--- sys/fs/hfs/hfs_vfsops.c     17 Dec 2008 20:51:35 -0000      1.20
+++ sys/fs/hfs/hfs_vfsops.c     22 Apr 2009 23:54:22 -0000
@@ -275,18 +275,19 @@ hfs_mount(struct mount *mp, const char *
        /*
         * 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: sys/fs/udf/udf_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/udf/udf_vfsops.c,v
retrieving revision 1.55
diff -u -p -r1.55 udf_vfsops.c
--- sys/fs/udf/udf_vfsops.c     8 Feb 2009 19:04:41 -0000       1.55
+++ sys/fs/udf/udf_vfsops.c     22 Apr 2009 23:54:22 -0000
@@ -378,17 +378,15 @@ udf_mount(struct mount *mp, const char *
         * 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: sys/ufs/ffs/ffs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.245
diff -u -p -r1.245 ffs_vfsops.c
--- sys/ufs/ffs/ffs_vfsops.c    29 Mar 2009 10:29:00 -0000      1.245
+++ sys/ufs/ffs/ffs_vfsops.c    22 Apr 2009 23:54:23 -0000
@@ -381,18 +381,19 @@ ffs_mount(struct mount *mp, const char *
        /*
         * 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);
Index: sys/ufs/ext2fs/ext2fs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vfsops.c,v
retrieving revision 1.142
diff -u -p -r1.142 ext2fs_vfsops.c
--- sys/ufs/ext2fs/ext2fs_vfsops.c      1 Mar 2009 15:59:57 -0000       1.142
+++ sys/ufs/ext2fs/ext2fs_vfsops.c      22 Apr 2009 23:54:23 -0000
@@ -380,18 +380,19 @@ ext2fs_mount(struct mount *mp, const cha
        /*
         * 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);


Home | Main Index | Thread Index | Old Index