summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2010-09-15 19:55:26 +0000
committermm <mm@FreeBSD.org>2010-09-15 19:55:26 +0000
commit619300afba60531f5444ebe6322d9492fce9361d (patch)
tree10d631120cb4e87e4c57fc165631b96818c04f03 /sys/cddl/contrib
parent1bb4df1f41a7b165af646cd4057f5a318e43eb88 (diff)
downloadFreeBSD-src-619300afba60531f5444ebe6322d9492fce9361d.zip
FreeBSD-src-619300afba60531f5444ebe6322d9492fce9361d.tar.gz
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
Diffstat (limited to 'sys/cddl/contrib')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c14
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c10
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c35
4 files changed, 40 insertions, 23 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h
index 25348d6..1945686 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h
@@ -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);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
index 156c1ee..48c3ebf 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
@@ -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.
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index 96c9734..30a1b315 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -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);
}
/*
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
index d83e8f4..18ff03b 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
@@ -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, vnode_t *tdvp, char *tnm, cred_t *cr,
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, char *name, cred_t *cr,
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, char *name, cred_t *cr,
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, char *name, cred_t *cr,
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.
*/
OpenPOWER on IntegriCloud