From owner-svn-src-all@FreeBSD.ORG Wed Sep 15 19:55:27 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0E00A106566C; Wed, 15 Sep 2010 19:55:27 +0000 (UTC) (envelope-from mm@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id EFA6F8FC21; Wed, 15 Sep 2010 19:55:26 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o8FJtQK8048793; Wed, 15 Sep 2010 19:55:26 GMT (envelope-from mm@svn.freebsd.org) Received: (from mm@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o8FJtQI8048787; Wed, 15 Sep 2010 19:55:26 GMT (envelope-from mm@svn.freebsd.org) Message-Id: <201009151955.o8FJtQI8048787@svn.freebsd.org> From: Martin Matuska Date: Wed, 15 Sep 2010 19:55:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r212694 - in head/sys/cddl: compat/opensolaris/sys contrib/opensolaris/uts/common/fs/zfs contrib/opensolaris/uts/common/fs/zfs/sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Sep 2010 19:55:27 -0000 Author: mm Date: Wed Sep 15 19:55:26 2010 New Revision: 212694 URL: http://svn.freebsd.org/changeset/base/212694 Log: 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) MFC after: 3 days Modified: head/sys/cddl/compat/opensolaris/sys/vnode.h head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Modified: head/sys/cddl/compat/opensolaris/sys/vnode.h ============================================================================== --- head/sys/cddl/compat/opensolaris/sys/vnode.h Wed Sep 15 19:40:42 2010 (r212693) +++ head/sys/cddl/compat/opensolaris/sys/vnode.h Wed Sep 15 19:55:26 2010 (r212694) @@ -76,6 +76,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: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h Wed Sep 15 19:40:42 2010 (r212693) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h Wed Sep 15 19:55:26 2010 (r212694) @@ -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: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c Wed Sep 15 19:40:42 2010 (r212693) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c Wed Sep 15 19:55:26 2010 (r212694) @@ -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: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Wed Sep 15 19:40:42 2010 (r212693) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Wed Sep 15 19:55:26 2010 (r212694) @@ -1163,8 +1163,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)) { @@ -1178,7 +1177,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; } @@ -1433,9 +1432,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: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Wed Sep 15 19:40:42 2010 (r212693) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Wed Sep 15 19:55:26 2010 (r212694) @@ -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 */ @@ -3357,7 +3356,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); } @@ -3875,6 +3874,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); @@ -3886,13 +3886,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); @@ -3901,7 +3918,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 @@ -3914,14 +3930,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) && @@ -3935,6 +3943,7 @@ top: return (error); } +top: /* * Attempt to lock directory; fail if entry already exists. */