mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
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
This commit is contained in:
parent
0e2b59be50
commit
d1ee63f836
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=212694
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
/*
|
||||
|
@ -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 @@ 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);
|
||||
}
|
||||
|
||||
owner = zfs_fuid_map_id(zfsvfs, szp->z_phys->zp_uid, cr, ZFS_OWNER);
|
||||
if (owner != crgetuid(cr) &&
|
||||
@ -3935,6 +3943,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.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user