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>