Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 24 Apr 2010 21:20:43 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r207162 - in user/kib/vm6/sys: ufs/ffs vm
Message-ID:  <201004242120.o3OLKhrB049697@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sat Apr 24 21:20:43 2010
New Revision: 207162
URL: http://svn.freebsd.org/changeset/base/207162

Log:
  Drop SUID/SGID on writes in ffs_extend.
  Unconditionally call VOP_EXTEND first time in write loop to let it
  drop s bits.

Modified:
  user/kib/vm6/sys/ufs/ffs/ffs_vnops.c
  user/kib/vm6/sys/vm/vm_readwrite.c

Modified: user/kib/vm6/sys/ufs/ffs/ffs_vnops.c
==============================================================================
--- user/kib/vm6/sys/ufs/ffs/ffs_vnops.c	Sat Apr 24 21:17:07 2010	(r207161)
+++ user/kib/vm6/sys/ufs/ffs/ffs_vnops.c	Sat Apr 24 21:20:43 2010	(r207162)
@@ -175,6 +175,18 @@ struct vop_vector ffs_fifoops2 = {
 	.vop_vptofh =		ffs_vptofh,
 };
 
+static void
+ffs_drop_suid(struct inode *ip, struct ucred *cred)
+{
+
+	if (ip->i_mode & (ISUID | ISGID)) {
+		if (priv_check_cred(cred, PRIV_VFS_RETAINSUGID, 0)) {
+			ip->i_mode &= ~(ISUID | ISGID);
+			DIP_SET(ip, i_mode, ip->i_mode);
+		}
+	}
+}
+
 /*
  * Synch an open file.
  */
@@ -818,13 +830,8 @@ ffs_write(ap)
 	 * we clear the setuid and setgid bits as a precaution against
 	 * tampering.
 	 */
-	if ((ip->i_mode & (ISUID | ISGID)) && resid > uio->uio_resid &&
-	    ap->a_cred) {
-		if (priv_check_cred(ap->a_cred, PRIV_VFS_RETAINSUGID, 0)) {
-			ip->i_mode &= ~(ISUID | ISGID);
-			DIP_SET(ip, i_mode, ip->i_mode);
-		}
-	}
+	if (resid > uio->uio_resid && ap->a_cred != NULL)
+		ffs_drop_suid(ip, ap->a_cred);
 	if (error) {
 		if (ioflag & IO_UNIT) {
 			(void)ffs_truncate(vp, osize,
@@ -1829,6 +1836,7 @@ ffs_extend(struct vop_extend_args *ap)
 	ip->i_size = size;
 	DIP_SET(ip, i_size, size);
 	ip->i_flag |= IN_CHANGE | IN_UPDATE;
+	ffs_drop_suid(ip, ap->a_cred);
 	return (0);
 
  slow:
@@ -1847,5 +1855,7 @@ ffs_extend(struct vop_extend_args *ap)
 		error = ffs_update(vp, 1);
 	} else
 		bawrite(bp);
+	if (error == 0)
+		ffs_drop_suid(ip, ap->a_cred);
 	return (error);
 }

Modified: user/kib/vm6/sys/vm/vm_readwrite.c
==============================================================================
--- user/kib/vm6/sys/vm/vm_readwrite.c	Sat Apr 24 21:17:07 2010	(r207161)
+++ user/kib/vm6/sys/vm/vm_readwrite.c	Sat Apr 24 21:20:43 2010	(r207162)
@@ -718,7 +718,7 @@ vnode_pager_write(struct vnode *vp, stru
 	ssize_t size, size1, osize, osize1, resid, sresid, written;
 	int error, vn_locked, wpmax, wp, i, pflags;
 	u_int bits;
-	boolean_t vnode_locked, freed, freed1;
+	boolean_t vnode_locked, freed, freed1, first_extend;
 	struct thread *td;
 
 	if (ioflags & (IO_EXT|IO_INVAL|IO_DIRECT))
@@ -734,6 +734,7 @@ vnode_pager_write(struct vnode *vp, stru
 	vn_locked = VOP_ISLOCKED(vp);
 	vnode_locked = TRUE;
 	error = 0;
+	first_extend = TRUE;
 
 	/*
 	 * Reversed logic from vnode_generic_putpages().
@@ -840,7 +841,7 @@ vnode_pager_write(struct vnode *vp, stru
 		/*
 		 * Extend the file if writing past end.
 		 */
-		if (osize1 < uio->uio_offset + size) {
+		if (osize1 < uio->uio_offset + size || first_extend) {
 			if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) {
 				VOP_UNLOCK(vp, 0);
 				vnode_locked = FALSE;
@@ -856,6 +857,7 @@ vnode_pager_write(struct vnode *vp, stru
 			vattr.va_size = uio->uio_offset + size;
 			error = VOP_EXTEND(vp, td->td_ucred, uio->uio_offset +
 			    size, ioflags);
+			first_extend = FALSE;
 		}
 		if (error != 0)
 			break;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201004242120.o3OLKhrB049697>