svn commit: r207162 - in user/kib/vm6/sys: ufs/ffs vm
Konstantin Belousov
kib at FreeBSD.org
Sat Apr 24 21:20:44 UTC 2010
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;
More information about the svn-src-user
mailing list