Date: Mon, 12 Oct 2009 20:36:55 +0000 (UTC) From: Pawel Jakub Dawidek <pjd@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r198001 - in stable/8/sys: . amd64/include/xen cddl/compat/opensolaris/kern cddl/compat/opensolaris/sys cddl/contrib/opensolaris cddl/contrib/opensolaris/uts/common/fs/zfs contrib/dev/a... Message-ID: <200910122036.n9CKatDW084962@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: pjd Date: Mon Oct 12 20:36:55 2009 New Revision: 198001 URL: http://svn.freebsd.org/changeset/base/198001 Log: MFC r197831,r197842,r197843,r197860,r197861: r197831: Fix situation where Mac OS X NFS client creates a file and when it tries to set ownership and mode in the same setattr operation, the mode was overwritten by secpolicy_vnode_setattr(). PR: kern/118320 Submitted by: Mark Thompson <info-gentoo@mark.thompson.bz> r197842: Fix white-spaces. r197843: On FreeBSD it is enough to report provider removal when orphan event is received, we don't have to do it on every ENXIO error in I/O path. Solaris has no GEOM so they have to handle it in a less clean way. r197860: File system owner is when uid matches and jail matches. r197861: Allow file system owner to modify system flags if securelevel permits. Approved by: re (kib) Modified: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c stable/8/sys/cddl/compat/opensolaris/sys/policy.h stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c 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/kern/opensolaris_policy.c ============================================================================== --- stable/8/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c Mon Oct 12 19:41:57 2009 (r198000) +++ stable/8/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c Mon Oct 12 20:36:55 2009 (r198001) @@ -78,12 +78,11 @@ secpolicy_fs_owner(struct mount *mp, str if (zfs_super_owner) { if (cred->cr_uid == mp->mnt_cred->cr_uid && - (!jailed(cred) || - cred->cr_prison == mp->mnt_cred->cr_prison)) { + cred->cr_prison == mp->mnt_cred->cr_prison) { return (0); } } - return (priv_check_cred(cred, PRIV_VFS_MOUNT_OWNER, 0)); + return (EPERM); } /* @@ -359,8 +358,11 @@ secpolicy_fs_mount_clearopts(cred_t *cr, * Check privileges for setting xvattr attributes */ int -secpolicy_xvattr(xvattr_t *xvap, uid_t owner, cred_t *cr, vtype_t vtype) +secpolicy_xvattr(struct vnode *vp, xvattr_t *xvap, uid_t owner, cred_t *cr, + vtype_t vtype) { + if (secpolicy_fs_owner(vp->v_mount, cr) == 0) + return (0); return (priv_check_cred(cr, PRIV_VFS_SYSFLAGS, 0)); } Modified: stable/8/sys/cddl/compat/opensolaris/sys/policy.h ============================================================================== --- stable/8/sys/cddl/compat/opensolaris/sys/policy.h Mon Oct 12 19:41:57 2009 (r198000) +++ stable/8/sys/cddl/compat/opensolaris/sys/policy.h Mon Oct 12 20:36:55 2009 (r198001) @@ -70,7 +70,8 @@ int secpolicy_setid_setsticky_clear(stru int secpolicy_fs_owner(struct mount *vfsp, struct ucred *cred); int secpolicy_fs_mount(cred_t *cr, vnode_t *mvp, struct mount *vfsp); void secpolicy_fs_mount_clearopts(cred_t *cr, struct mount *vfsp); -int secpolicy_xvattr(xvattr_t *xvap, uid_t owner, cred_t *cr, vtype_t vtype); +int secpolicy_xvattr(struct vnode *vp, xvattr_t *xvap, uid_t owner, + cred_t *cr, vtype_t vtype); #endif /* _KERNEL */ Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c ============================================================================== --- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c Mon Oct 12 19:41:57 2009 (r198000) +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c Mon Oct 12 20:36:55 2009 (r198001) @@ -433,7 +433,7 @@ vdev_geom_open_by_guid(vdev_t *vd) if (cp != NULL) { len = strlen(cp->provider->name) + strlen("/dev/") + 1; buf = kmem_alloc(len, KM_SLEEP); - + snprintf(buf, len, "/dev/%s", cp->provider->name); spa_strfree(vd->vdev_path); vd->vdev_path = buf; @@ -662,26 +662,6 @@ sendreq: static void vdev_geom_io_done(zio_t *zio) { - - /* - * If the device returned ENXIO, then attempt we should verify if GEOM - * provider has been removed. If this is the case, then we trigger an - * asynchronous removal of the device. - */ - if (zio->io_error == ENXIO) { - vdev_t *vd = zio->io_vd; - vdev_geom_ctx_t *ctx; - struct g_provider *pp = NULL; - - ctx = vd->vdev_tsd; - if (ctx != NULL && ctx->gc_consumer != NULL) - pp = ctx->gc_consumer->provider; - - if (pp == NULL || (pp->flags & G_PF_ORPHAN)) { - vd->vdev_remove_wanted = B_TRUE; - spa_async_request(zio->io_spa, SPA_ASYNC_REMOVE); - } - } } vdev_ops_t vdev_geom_ops = { 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 Mon Oct 12 19:41:57 2009 (r198000) +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Mon Oct 12 20:36:55 2009 (r198001) @@ -1306,7 +1306,7 @@ zfs_create(vnode_t *dvp, char *name, vat } if (vap->va_mask & AT_XVATTR) { - if ((error = secpolicy_xvattr((xvattr_t *)vap, + if ((error = secpolicy_xvattr(dvp, (xvattr_t *)vap, crgetuid(cr), cr, vap->va_type)) != 0) { ZFS_EXIT(zfsvfs); return (error); @@ -1758,7 +1758,7 @@ zfs_mkdir(vnode_t *dvp, char *dirname, v zf |= ZCILOOK; if (vap->va_mask & AT_XVATTR) - if ((error = secpolicy_xvattr((xvattr_t *)vap, + if ((error = secpolicy_xvattr(dvp, (xvattr_t *)vap, crgetuid(cr), cr, vap->va_type)) != 0) { ZFS_EXIT(zfsvfs); return (error); @@ -2538,6 +2538,7 @@ zfs_setattr(vnode_t *vp, vattr_t *vap, i vattr_t oldva; uint_t mask = vap->va_mask; uint_t saved_mask; + uint64_t saved_mode; int trim_mask = 0; uint64_t new_mode; znode_t *attrzp; @@ -2766,6 +2767,13 @@ top: if (trim_mask) { saved_mask = vap->va_mask; vap->va_mask &= ~trim_mask; + if (trim_mask & AT_MODE) { + /* + * Save the mode, as secpolicy_vnode_setattr() + * will overwrite it with ova.va_mode. + */ + saved_mode = vap->va_mode; + } } err = secpolicy_vnode_setattr(cr, vp, vap, &oldva, flags, (int (*)(void *, int, cred_t *))zfs_zaccess_unix, zp); @@ -2774,8 +2782,16 @@ top: return (err); } - if (trim_mask) + if (trim_mask) { vap->va_mask |= saved_mask; + if (trim_mask & AT_MODE) { + /* + * Recover the mode after + * secpolicy_vnode_setattr(). + */ + vap->va_mode = saved_mode; + } + } } /* @@ -4182,12 +4198,6 @@ zfs_freebsd_setattr(ap) if ((fflags & ~(SF_IMMUTABLE|SF_APPEND|SF_NOUNLINK|UF_NODUMP)) != 0) return (EOPNOTSUPP); /* - * Callers may only modify the file flags on objects they - * have VADMIN rights for. - */ - if ((error = VOP_ACCESS(vp, VADMIN, cred, curthread)) != 0) - return (error); - /* * Unprivileged processes are not permitted to unset system * flags, or modify flags if any system flags are set. * Privileged non-jail processes may not modify system flags @@ -4197,14 +4207,21 @@ zfs_freebsd_setattr(ap) * is non-zero; otherwise, they behave like unprivileged * processes. */ - if (priv_check_cred(cred, PRIV_VFS_SYSFLAGS, 0) == 0) { + if (secpolicy_fs_owner(vp->v_mount, cred) == 0 || + priv_check_cred(cred, PRIV_VFS_SYSFLAGS, 0) == 0) { if (zflags & (ZFS_IMMUTABLE | ZFS_APPENDONLY | ZFS_NOUNLINK)) { error = securelevel_gt(cred, 0); - if (error) + if (error != 0) return (error); } } else { + /* + * Callers may only modify the file flags on objects they + * have VADMIN rights for. + */ + if ((error = VOP_ACCESS(vp, VADMIN, cred, curthread)) != 0) + return (error); if (zflags & (ZFS_IMMUTABLE | ZFS_APPENDONLY | ZFS_NOUNLINK)) { return (EPERM);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910122036.n9CKatDW084962>