Author: mm
Date: Sat Sep 18 08:45:43 2010
New Revision: 212820
URL: http://svn.freebsd.org/changeset/base/212820

Log:
  MFC r212694:
  
  Fix kernel panic when moving a file to .zfs/shares
  Fix possible loss of correct error return code in ZFS mount
  
  OpenSolaris revisions and Bug IDs:
  
  11824:53128e5db7cf
  6863610       ZFS mount can lose correct error return
  
  12079:13822b941977
  6939941       problem with moving files in zfs (142901-12)
  
  Approved by:  delphij (mentor)
  Obtained from:        OpenSolaris (Bug ID 6863610, 6939941)

Modified:
  stable/8/sys/cddl/compat/opensolaris/sys/vnode.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/cddl/compat/opensolaris/sys/vnode.h
==============================================================================
--- stable/8/sys/cddl/compat/opensolaris/sys/vnode.h    Sat Sep 18 08:25:12 
2010        (r212819)
+++ stable/8/sys/cddl/compat/opensolaris/sys/vnode.h    Sat Sep 18 08:45:43 
2010        (r212820)
@@ -74,6 +74,7 @@ vn_is_readonly(vnode_t *vp)
 #define        vn_invalid(vp)          do { } while (0)
 #define        vn_renamepath(tdvp, svp, tnm, lentnm)   do { } while (0)
 #define        vn_free(vp)             do { } while (0)
+#define        vn_matchops(vp, vops)   ((vp)->v_op == &(vops))
 
 #define        VN_HOLD(v)      vref(v)
 #define        VN_RELE(v)      vrele(v)

Modified: 
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h
==============================================================================
--- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h    
Sat Sep 18 08:25:12 2010        (r212819)
+++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h    
Sat Sep 18 08:45:43 2010        (r212820)
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef        _ZFS_CTLDIR_H
@@ -48,6 +47,7 @@ void zfsctl_destroy(zfsvfs_t *);
 vnode_t *zfsctl_root(znode_t *);
 void zfsctl_init(void);
 void zfsctl_fini(void);
+boolean_t zfsctl_is_node(vnode_t *);
 
 int zfsctl_rename_snapshot(const char *from, const char *to);
 int zfsctl_destroy_snapshot(const char *snapname, int force);

Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
==============================================================================
--- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c        
Sat Sep 18 08:25:12 2010        (r212819)
+++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c        
Sat Sep 18 08:45:43 2010        (r212820)
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -152,6 +151,17 @@ zfsctl_fini(void)
 {
 }
 
+boolean_t
+zfsctl_is_node(vnode_t *vp)
+{
+       return (vn_matchops(vp, zfsctl_ops_root) ||
+           vn_matchops(vp, zfsctl_ops_snapdir) ||
+           vn_matchops(vp, zfsctl_ops_snapshot) ||
+           vn_matchops(vp, zfsctl_ops_shares) ||
+           vn_matchops(vp, zfsctl_ops_shares_dir));
+
+}
+
 /*
  * Return the inode number associated with the 'snapshot' or
  * 'shares' directory.

Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
==============================================================================
--- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c        
Sat Sep 18 08:25:12 2010        (r212819)
+++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c        
Sat Sep 18 08:45:43 2010        (r212820)
@@ -1152,8 +1152,7 @@ zfs_mount(vfs_t *vfsp)
         */
        error = secpolicy_fs_mount(cr, mvp, vfsp);
        if (error) {
-               error = dsl_deleg_access(osname, ZFS_DELEG_PERM_MOUNT, cr);
-               if (error != 0)
+               if (dsl_deleg_access(osname, ZFS_DELEG_PERM_MOUNT, cr) != 0)
                        goto out;
 
                if (!(vfsp->vfs_flag & MS_REMOUNT)) {
@@ -1167,7 +1166,7 @@ zfs_mount(vfs_t *vfsp)
                        vattr.va_mask = AT_UID;
 
                        vn_lock(mvp, LK_SHARED | LK_RETRY);
-                       if (error = VOP_GETATTR(mvp, &vattr, cr)) {
+                       if (VOP_GETATTR(mvp, &vattr, cr)) {
                                VOP_UNLOCK(mvp, 0);
                                goto out;
                        }
@@ -1422,9 +1421,8 @@ zfs_umount(vfs_t *vfsp, int fflag)
 
        ret = secpolicy_fs_unmount(cr, vfsp);
        if (ret) {
-               ret = dsl_deleg_access((char *)refstr_value(vfsp->vfs_resource),
-                   ZFS_DELEG_PERM_MOUNT, cr);
-               if (ret)
+               if (dsl_deleg_access((char *)refstr_value(vfsp->vfs_resource),
+                   ZFS_DELEG_PERM_MOUNT, cr))
                        return (ret);
        }
        /*

Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Sat Sep 
18 08:25:12 2010        (r212819)
+++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Sat Sep 
18 08:45:43 2010        (r212820)
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /* Portions Copyright 2007 Jeremy Teo */
@@ -3344,7 +3343,7 @@ zfs_rename(vnode_t *sdvp, char *snm, vno
        if (VOP_REALVP(tdvp, &realvp, ct) == 0)
                tdvp = realvp;
 
-       if (tdvp->v_vfsp != sdvp->v_vfsp) {
+       if (tdvp->v_vfsp != sdvp->v_vfsp || zfsctl_is_node(tdvp)) {
                ZFS_EXIT(zfsvfs);
                return (EXDEV);
        }
@@ -3862,6 +3861,7 @@ zfs_link(vnode_t *tdvp, vnode_t *svp, ch
        vnode_t         *realvp;
        int             error;
        int             zf = ZNEW;
+       uint64_t        parent;
        uid_t           owner;
 
        ASSERT(tdvp->v_type == VDIR);
@@ -3873,13 +3873,30 @@ zfs_link(vnode_t *tdvp, vnode_t *svp, ch
        if (VOP_REALVP(svp, &realvp, ct) == 0)
                svp = realvp;
 
-       if (svp->v_vfsp != tdvp->v_vfsp) {
+       /*
+        * POSIX dictates that we return EPERM here.
+        * Better choices include ENOTSUP or EISDIR.
+        */
+       if (svp->v_type == VDIR) {
+               ZFS_EXIT(zfsvfs);
+               return (EPERM);
+       }
+
+       if (svp->v_vfsp != tdvp->v_vfsp || zfsctl_is_node(svp)) {
                ZFS_EXIT(zfsvfs);
                return (EXDEV);
        }
+
        szp = VTOZ(svp);
        ZFS_VERIFY_ZP(szp);
 
+       /* Prevent links to .zfs/shares files */
+
+       if (szp->z_phys->zp_parent == zfsvfs->z_shares_dir) {
+               ZFS_EXIT(zfsvfs);
+               return (EPERM);
+       }
+
        if (zfsvfs->z_utf8 && u8_validate(name,
            strlen(name), NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
                ZFS_EXIT(zfsvfs);
@@ -3888,7 +3905,6 @@ zfs_link(vnode_t *tdvp, vnode_t *svp, ch
        if (flags & FIGNORECASE)
                zf |= ZCILOOK;
 
-top:
        /*
         * We do not support links between attributes and non-attributes
         * because of the potential security risk of creating links
@@ -3901,14 +3917,6 @@ top:
                return (EINVAL);
        }
 
-       /*
-        * POSIX dictates that we return EPERM here.
-        * Better choices include ENOTSUP or EISDIR.
-        */
-       if (svp->v_type == VDIR) {
-               ZFS_EXIT(zfsvfs);
-               return (EPERM);
-       }
 
        owner = zfs_fuid_map_id(zfsvfs, szp->z_phys->zp_uid, cr, ZFS_OWNER);
        if (owner != crgetuid(cr) &&
@@ -3922,6 +3930,7 @@ top:
                return (error);
        }
 
+top:
        /*
         * Attempt to lock directory; fail if entry already exists.
         */
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to