Kernel - fix access checks
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 26 Aug 2009 17:40:41 +0000 (10:40 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 26 Aug 2009 17:43:15 +0000 (10:43 -0700)
* VOP_ACCESS() is used for more then just access().  UFS and other
  filesystems (but not HAMMER) were calling it in the open/create/rename/
  unlink paths.  The uid/gid must be used in those cases, not the ruid/rgid.

  Add a VOP_EACCESS() macro which passes the appropriate flag to use the
  uid/gid instead of the ruid/rgid, and adjust the filesystems to use this
  macro.

Reported-by: Stathis Kamperis <ekamperi@gmail.com>
18 files changed:
sys/sys/vfsops.h
sys/vfs/gnu/ext2fs/ext2_lookup.c
sys/vfs/gnu/ext2fs/ext2_vfsops.c
sys/vfs/gnu/ext2fs/ext2_vnops.c
sys/vfs/hpfs/hpfs_vnops.c
sys/vfs/isofs/cd9660/cd9660_vfsops.c
sys/vfs/msdosfs/msdosfs_lookup.c
sys/vfs/msdosfs/msdosfs_vfsops.c
sys/vfs/msdosfs/msdosfs_vnops.c
sys/vfs/nfs/nfs_serv.c
sys/vfs/nwfs/nwfs_ioctl.c
sys/vfs/nwfs/nwfs_vnops.c
sys/vfs/smbfs/smbfs_vnops.c
sys/vfs/udf/udf_vfsops.c
sys/vfs/ufs/ffs_vfsops.c
sys/vfs/ufs/ufs_lookup.c
sys/vfs/ufs/ufs_vnops.c
sys/vfs/union/union_subr.c

index 3717d0d..94d2b6f 100644 (file)
@@ -70,6 +70,9 @@
 #ifndef _SYS_BUF_H_
 #include <sys/buf.h>   /* buf_cmd_t */
 #endif
+#ifndef _SYS_FCNTL_H_
+#include <sys/fcntl.h> /* AT_EACCESS */
+#endif
 
 struct syslink_desc;
 struct vnode;
@@ -976,6 +979,8 @@ extern struct syslink_desc vop_nrename_desc;
        vop_close(*(vp)->v_ops, vp, fflag)
 #define VOP_ACCESS(vp, mode, cred)                     \
        vop_access(*(vp)->v_ops, vp, mode, 0, cred)
+#define VOP_EACCESS(vp, mode, cred)                    \
+       vop_access(*(vp)->v_ops, vp, mode, AT_EACCESS, cred)
 #define VOP_ACCESS_FLAGS(vp, mode, flags, cred)                \
        vop_access(*(vp)->v_ops, vp, mode, flags, cred)
 #define VOP_GETATTR(vp, vap)                           \
index e1b72d1..48fa130 100644 (file)
@@ -490,7 +490,7 @@ searchloop:
                 * Access for write is interpreted as allowing
                 * creation of files in the directory.
                 */
-               if ((error = VOP_ACCESS(vdp, VWRITE, cred)) != 0)
+               if ((error = VOP_EACCESS(vdp, VWRITE, cred)) != 0)
                        return (error);
                /*
                 * Return an indication of where the new directory
@@ -566,7 +566,7 @@ found:
                /*
                 * Write access to directory required to delete files.
                 */
-               if ((error = VOP_ACCESS(vdp, VWRITE, cred)) != 0)
+               if ((error = VOP_EACCESS(vdp, VWRITE, cred)) != 0)
                        return (error);
                /*
                 * Return pointer to current entry in dp->i_offset,
@@ -611,7 +611,7 @@ found:
         * regular file, or empty directory.
         */
        if (nameiop == NAMEI_RENAME && wantparent) {
-               if ((error = VOP_ACCESS(vdp, VWRITE, cred)) != 0)
+               if ((error = VOP_EACCESS(vdp, VWRITE, cred)) != 0)
                        return (error);
                /*
                 * Careful about locking second inode.
index f2ece19..b48a9fa 100644 (file)
@@ -325,7 +325,7 @@ ext2_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
                         */
                        if (cred->cr_uid != 0) {
                                vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-                               error = VOP_ACCESS(devvp, VREAD | VWRITE, cred);
+                               error = VOP_EACCESS(devvp, VREAD | VWRITE, cred);
                                if (error) {
                                        vn_unlock(devvp);
                                        return (error);
@@ -389,7 +389,7 @@ ext2_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
                if ((mp->mnt_flag & MNT_RDONLY) == 0)
                        accessmode |= VWRITE;
                vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-               if ((error = VOP_ACCESS(devvp, accessmode, cred)) != 0) {
+               if ((error = VOP_EACCESS(devvp, accessmode, cred)) != 0) {
                        vput(devvp);
                        return (error);
                }
index 0e71be7..1b7fa73 100644 (file)
@@ -517,7 +517,7 @@ abortit:
         * to namei, as the parent directory is unlocked by the
         * call to checkpath().
         */
-       error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred);
+       error = VOP_EACCESS(fvp, VWRITE, tcnp->cn_cred);
        vn_unlock(fvp);
 
        /*
@@ -1488,7 +1488,7 @@ ext2_setattr(struct vop_setattr_args *ap)
                if (cred->cr_uid != ip->i_uid &&
                    (error = priv_check_cred(cred, PRIV_VFS_SETATTR, 0)) &&
                    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
-                   (error = VOP_ACCESS(vp, VWRITE, cred))))
+                   (error = VOP_EACCESS(vp, VWRITE, cred))))
                        return (error);
                if (vap->va_atime.tv_sec != VNOVAL)
                        ip->i_flag |= IN_ACCESS;
index 8ca0b41..9dbcb3e 100644 (file)
@@ -533,7 +533,7 @@ hpfs_setattr(struct vop_setattr_args *ap)
                if (cred->cr_uid != hp->h_uid &&
                    (error = priv_check_cred(cred, PRIV_VFS_SETATTR, 0)) &&
                    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
-                   (error = VOP_ACCESS(vp, VWRITE, cred))))
+                   (error = VOP_EACCESS(vp, VWRITE, cred))))
                        return (error);
                if (vap->va_atime.tv_sec != VNOVAL)
                        hp->h_atime = vap->va_atime.tv_sec;
@@ -982,7 +982,7 @@ hpfs_lookup(struct vop_old_lookup_args *ap)
                return (EOPNOTSUPP);
        }
 
-       error = VOP_ACCESS(dvp, VEXEC, cred);
+       error = VOP_EACCESS(dvp, VEXEC, cred);
        if(error)
                return (error);
 
@@ -1035,7 +1035,7 @@ hpfs_lookup(struct vop_old_lookup_args *ap)
                         dep->de_fnode, dep->de_cpid));
 
                if (nameiop == NAMEI_DELETE) {
-                       error = VOP_ACCESS(dvp, VWRITE, cred);
+                       error = VOP_EACCESS(dvp, VWRITE, cred);
                        if (error) {
                                brelse(bp);
                                return (error);
index bfa2967..cfab5de 100644 (file)
@@ -232,7 +232,7 @@ cd9660_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
         */
        accessmode = VREAD;
        vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-       error = VOP_ACCESS(devvp, accessmode, cred);
+       error = VOP_EACCESS(devvp, accessmode, cred);
        if (error) 
                error = priv_check_cred(cred, PRIV_ROOT, 0);
        if (error) {
index 729dcdd..01cb43d 100644 (file)
@@ -337,7 +337,7 @@ notfound:
                 * Access for write is interpreted as allowing
                 * creation of files in the directory.
                 */
-               error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred);
+               error = VOP_EACCESS(vdp, VWRITE, cnp->cn_cred);
                if (error)
                        return (error);
                /*
@@ -429,7 +429,7 @@ foundroot:
                /*
                 * Write access to directory required to delete files.
                 */
-               error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred);
+               error = VOP_EACCESS(vdp, VWRITE, cnp->cn_cred);
                if (error)
                        return (error);
 
@@ -463,7 +463,7 @@ foundroot:
                if (blkoff == MSDOSFSROOT_OFS)
                        return EROFS;                   /* really? XXX */
 
-               error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred);
+               error = VOP_EACCESS(vdp, VWRITE, cnp->cn_cred);
                if (error)
                        return (error);
 
index 8a39bb2..7cdc8ce 100644 (file)
@@ -201,7 +201,7 @@ msdosfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
                        devvp = pmp->pm_devvp;
                        vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
                        if (cred->cr_uid != 0) {
-                               error = VOP_ACCESS(devvp, VREAD | VWRITE, cred);
+                               error = VOP_EACCESS(devvp, VREAD | VWRITE, cred);
                                if (error) {
                                        vn_unlock(devvp);
                                        return (error);
@@ -254,7 +254,7 @@ msdosfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
                if ((mp->mnt_flag & MNT_RDONLY) == 0)
                        accessmode |= VWRITE;
                vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-               error = VOP_ACCESS(devvp, accessmode, cred);
+               error = VOP_EACCESS(devvp, accessmode, cred);
                if (error) {
                        vput(devvp);
                        return (error);
index 7b7f76c..fdb549c 100644 (file)
@@ -434,7 +434,7 @@ msdosfs_setattr(struct vop_setattr_args *ap)
                if (cred->cr_uid != pmp->pm_uid &&
                    (error = priv_check_cred(cred, PRIV_VFS_SETATTR, 0)) &&
                    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
-                   (error = VOP_ACCESS(ap->a_vp, VWRITE, cred))))
+                   (error = VOP_EACCESS(ap->a_vp, VWRITE, cred))))
                        return (error);
                if (vp->v_type != VDIR) {
                        if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 &&
@@ -1023,7 +1023,7 @@ abortit:
         * to namei, as the parent directory is unlocked by the
         * call to doscheckpath().
         */
-       error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred);
+       error = VOP_EACCESS(fvp, VWRITE, tcnp->cn_cred);
        vn_unlock(fvp);
        if (VTODE(fdvp)->de_StartCluster != VTODE(tdvp)->de_StartCluster)
                newparent = 1;
index 6d21042..86a4b0c 100644 (file)
@@ -3984,7 +3984,7 @@ nfsrv_access(struct mount *mp, struct vnode *vp, int flags, struct ucred *cred,
        error = VOP_GETATTR(vp, &vattr);
        if (error)
                return (error);
-       error = VOP_ACCESS(vp, flags, cred);
+       error = VOP_ACCESS(vp, flags, cred);    /* XXX ruid/rgid vs uid/gid */
        /*
         * Allow certain operations for the owner (reads and writes
         * on files that are already open).
index 5410ce5..5dd542c 100644 (file)
@@ -78,7 +78,7 @@ nwfs_ioctl(struct vop_ioctl_args *ap)
                *(int*)data = hp->nh_id;
                break;
            case NWFSIOC_GETEINFO:
-               if ((error = VOP_ACCESS(vp, VEXEC, cred))) break;
+               if ((error = VOP_EACCESS(vp, VEXEC, cred))) break;
                fap = data;
                error = ncp_obtain_info(nmp, np->n_fid.f_id, 0, NULL, fap,
                    td, ap->a_cred);
@@ -86,7 +86,7 @@ nwfs_ioctl(struct vop_ioctl_args *ap)
                fap->nameLen = np->n_nmlen;
                break;
            case NWFSIOC_GETNS:
-               if ((error = VOP_ACCESS(vp, VEXEC, cred))) break;
+               if ((error = VOP_EACCESS(vp, VEXEC, cred))) break;
                *(int*)data = nmp->name_space;
                break;
            default:
index 03ffb83..dc068b6 100644 (file)
@@ -832,7 +832,7 @@ nwfs_lookup(struct vop_old_lookup_args *ap)
 
        if ((mp->mnt_flag & MNT_RDONLY) && nameiop != NAMEI_LOOKUP)
                return (EROFS);
-       if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred)))
+       if ((error = VOP_EACCESS(dvp, VEXEC, cnp->cn_cred)))
                return (error);
        lockparent = flags & CNP_LOCKPARENT;
        wantparent = flags & (CNP_LOCKPARENT | CNP_WANTPARENT);
@@ -891,7 +891,7 @@ kprintf("dvp %d:%d:%d\n", (int)mp, (int)dvp->v_flag & VROOT, (int)flags & CNP_IS
        }*/
        /* handle DELETE case ... */
        if (nameiop == NAMEI_DELETE) {  /* delete last component */
-               error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred);
+               error = VOP_EACCESS(dvp, VWRITE, cnp->cn_cred);
                if (error) return (error);
                if (NWCMPF(&dnp->n_fid, &fid)) {        /* we found ourselfs */
                        vref(dvp);
@@ -905,7 +905,7 @@ kprintf("dvp %d:%d:%d\n", (int)mp, (int)dvp->v_flag & VROOT, (int)flags & CNP_IS
                return (0);
        }
        if (nameiop == NAMEI_RENAME && wantparent) {
-               error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred);
+               error = VOP_EACCESS(dvp, VWRITE, cnp->cn_cred);
                if (error) return (error);
                if (NWCMPF(&dnp->n_fid, &fid)) return EISDIR;
                error = nwfs_nget(mp, fid, fap, dvp, &vp);
index 6695918..d0f7075 100644 (file)
@@ -355,7 +355,7 @@ smbfs_setattr(struct vop_setattr_args *ap)
                if (ap->a_cred->cr_uid != VTOSMBFS(vp)->sm_args.uid &&
                    (error = priv_check_cred(ap->a_cred, PRIV_VFS_SETATTR, 0)) &&
                    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
-                   (error = VOP_ACCESS(vp, VWRITE, ap->a_cred))))
+                   (error = VOP_EACCESS(vp, VWRITE, ap->a_cred))))
                        return (error);
 #if 0
                if (mtime == NULL)
@@ -841,7 +841,7 @@ smbfs_getextattr(struct vop_getextattr_args *ap)
        char buf[10];
        int i, attr, error;
 
-       error = VOP_ACCESS(vp, VREAD, cred);
+       error = VOP_EACCESS(vp, VREAD, cred);
        if (error)
                return error;
        error = VOP_GETATTR(vp, &vattr);
@@ -1039,7 +1039,7 @@ smbfs_lookup(struct vop_old_lookup_args *ap)
 #endif
        if ((mp->mnt_flag & MNT_RDONLY) && nameiop != NAMEI_LOOKUP)
                return EROFS;
-       if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred)) != 0)
+       if ((error = VOP_EACCESS(dvp, VEXEC, cnp->cn_cred)) != 0)
                return error;
        lockparent = flags & CNP_LOCKPARENT;
        wantparent = flags & (CNP_LOCKPARENT | CNP_WANTPARENT);
@@ -1072,7 +1072,7 @@ smbfs_lookup(struct vop_old_lookup_args *ap)
                 * Handle RENAME or CREATE case...
                 */
                if ((nameiop == NAMEI_CREATE || nameiop == NAMEI_RENAME) && wantparent) {
-                       error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred);
+                       error = VOP_EACCESS(dvp, VWRITE, cnp->cn_cred);
                        if (error)
                                return error;
                        if (!lockparent) {
@@ -1089,7 +1089,7 @@ smbfs_lookup(struct vop_old_lookup_args *ap)
         * handle DELETE case ...
         */
        if (nameiop == NAMEI_DELETE) {  /* delete last component */
-               error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred);
+               error = VOP_EACCESS(dvp, VWRITE, cnp->cn_cred);
                if (error)
                        return error;
                if (isdot) {
@@ -1108,7 +1108,7 @@ smbfs_lookup(struct vop_old_lookup_args *ap)
                return 0;
        }
        if (nameiop == NAMEI_RENAME && wantparent) {
-               error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred);
+               error = VOP_EACCESS(dvp, VWRITE, cnp->cn_cred);
                if (error)
                        return error;
                if (isdot)
index ebe6b2b..50db59c 100644 (file)
@@ -173,7 +173,7 @@ udf_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
 
        /* Check the access rights on the mount device */
        vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-       error = VOP_ACCESS(devvp, VREAD, cred);
+       error = VOP_EACCESS(devvp, VREAD, cred);
        if (error)
                error = priv_check_cred(cred, PRIV_ROOT, 0);
        if (error) {
index 13f5f6d..45820fa 100644 (file)
@@ -223,7 +223,7 @@ ffs_mount(struct mount *mp,         /* mount struct pointer */
                         */
                        if (cred->cr_uid != 0) {
                                vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-                               if ((error = VOP_ACCESS(devvp, VREAD | VWRITE,
+                               if ((error = VOP_EACCESS(devvp, VREAD | VWRITE,
                                    cred)) != 0) {
                                        vn_unlock(devvp);
                                        return (error);
@@ -302,7 +302,7 @@ ffs_mount(struct mount *mp,         /* mount struct pointer */
                if ((mp->mnt_flag & MNT_RDONLY) == 0)
                        accessmode |= VWRITE;
                vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-               if ((error = VOP_ACCESS(devvp, accessmode, cred)) != 0) {
+               if ((error = VOP_EACCESS(devvp, accessmode, cred)) != 0) {
                        vput(devvp);
                        return (error);
                }
index a6bbafe..df7af7f 100644 (file)
@@ -381,7 +381,7 @@ notfound:
                 * Access for write is interpreted as allowing
                 * creation of files in the directory.
                 */
-               error = VOP_ACCESS(vdp, VWRITE, cred);
+               error = VOP_EACCESS(vdp, VWRITE, cred);
                if (error)
                        return (error);
                /*
@@ -465,7 +465,7 @@ found:
                /*
                 * Write access to directory required to delete files.
                 */
-               error = VOP_ACCESS(vdp, VWRITE, cred);
+               error = VOP_EACCESS(vdp, VWRITE, cred);
                if (error)
                        return (error);
                /*
@@ -520,7 +520,7 @@ found:
         * regular file, or empty directory.
         */
        if (nameiop == NAMEI_RENAME && wantparent) {
-               if ((error = VOP_ACCESS(vdp, VWRITE, cred)) != 0)
+               if ((error = VOP_EACCESS(vdp, VWRITE, cred)) != 0)
                        return (error);
                /*
                 * Careful about locking second inode.
index 179b603..39cfa63 100644 (file)
@@ -472,7 +472,7 @@ ufs_setattr(struct vop_setattr_args *ap)
                if (cred->cr_uid != ip->i_uid &&
                    (error = priv_check_cred(cred, PRIV_VFS_SETATTR, 0)) &&
                    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
-                   (error = VOP_ACCESS(vp, VWRITE, cred))))
+                   (error = VOP_EACCESS(vp, VWRITE, cred))))
                        return (error);
                if (vap->va_atime.tv_sec != VNOVAL)
                        ip->i_flag |= IN_ACCESS;
@@ -952,7 +952,7 @@ abortit:
         * to namei, as the parent directory is unlocked by the
         * call to checkpath().
         */
-       error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred);
+       error = VOP_EACCESS(fvp, VWRITE, tcnp->cn_cred);
        vn_unlock(fvp);
 
        /*
index 5833a14..1552065 100644 (file)
@@ -725,7 +725,7 @@ union_copyup(struct union_node *un, int docopy, struct ucred *cred,
         * be copied to upper layer.
         */
        vn_lock(un->un_lowervp, LK_EXCLUSIVE | LK_RETRY);
-       error = VOP_ACCESS(un->un_lowervp, VREAD, cred);
+       error = VOP_EACCESS(un->un_lowervp, VREAD, cred);
        vn_unlock(un->un_lowervp);
        if (error)
                return (error);