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...

Pawel Jakub Dawidek pjd at FreeBSD.org
Mon Oct 12 20:36:55 UTC 2009


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 at 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);


More information about the svn-src-all mailing list