Skip to content

Commit

Permalink
6939941 problem with moving files in zfs
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Shellenbaum authored and Mark Shellenbaum committed Apr 6, 2010
1 parent 32b54db commit d39ee14
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 17 deletions.
4 changes: 2 additions & 2 deletions usr/src/uts/common/fs/zfs/sys/zfs_ctldir.h
Expand Up @@ -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
Expand Down Expand Up @@ -49,6 +48,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);
Expand Down
14 changes: 12 additions & 2 deletions usr/src/uts/common/fs/zfs/zfs_ctldir.c
Expand Up @@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
*/

/*
Expand Down Expand Up @@ -186,6 +185,17 @@ zfsctl_fini(void)
zfsctl_ops_shares_dir = NULL;
}

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.
Expand Down
40 changes: 27 additions & 13 deletions usr/src/uts/common/fs/zfs/zfs_vnops.c
Expand Up @@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2010 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 */
Expand Down Expand Up @@ -3248,7 +3247,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);
}
Expand Down Expand Up @@ -3747,6 +3746,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;

ASSERT(tdvp->v_type == VDIR);

Expand All @@ -3757,13 +3757,35 @@ 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 ((error = sa_lookup(szp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs),
&parent, sizeof (uint64_t))) != 0) {
ZFS_EXIT(zfsvfs);
return (error);
}
if (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);
Expand All @@ -3772,7 +3794,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
Expand All @@ -3784,14 +3805,6 @@ zfs_link(vnode_t *tdvp, vnode_t *svp, char *name, cred_t *cr,
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);
}

if (szp->z_uid != crgetuid(cr) &&
secpolicy_basic_link(cr) != 0) {
Expand All @@ -3804,6 +3817,7 @@ zfs_link(vnode_t *tdvp, vnode_t *svp, char *name, cred_t *cr,
return (error);
}

top:
/*
* Attempt to lock directory; fail if entry already exists.
*/
Expand Down

0 comments on commit d39ee14

Please sign in to comment.