patch-1.3.60 linux/fs/read_write.c

Next file: linux/fs/umsdos/dir.c
Previous file: linux/fs/proc/root.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.59/linux/fs/read_write.c linux/fs/read_write.c
@@ -138,19 +138,23 @@
 	error = verify_area(VERIFY_READ,buf,count);
 	if (error)
 		return error;
-	down(&inode->i_sem);
-	written = file->f_op->write(inode,file,buf,count);
-	up(&inode->i_sem);
 	/*
 	 * If data has been written to the file, remove the setuid and
-	 * the setgid bits
+	 * the setgid bits. We do it anyway otherwise there is an
+	 * extremely exploitable race - does your OS get it right |->
+	 *
+	 * Set ATTR_FORCE so it will always be changed.
 	 */
-	if (written > 0 && !suser() && (inode->i_mode & (S_ISUID | S_ISGID))) {
+	if (!suser() && (inode->i_mode & (S_ISUID | S_ISGID))) {
 		struct iattr newattrs;
 		newattrs.ia_mode = inode->i_mode & ~(S_ISUID | S_ISGID);
-		newattrs.ia_valid = ATTR_MODE;
+		newattrs.ia_valid = ATTR_CTIME | ATTR_MODE | ATTR_FORCE;
 		notify_change(inode, &newattrs);
 	}
+
+	down(&inode->i_sem);
+	written = file->f_op->write(inode,file,buf,count);
+	up(&inode->i_sem);
 	return written;
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this