Commit f7d25a8e authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] setuid clearing fix

From: Andries.Brouwer@cwi.nl

jpcartal@free.fr writes:

	I noticed that contrary to what was happening with 2.4.x kernel, suid
	root files don't loose their suid bit when they get overwritten by a
	normal user (see example below)

	Is this the intended behaviour or a bug ?

	Example :

	[root@localhost test]# chown root ~cartaljp/test/suid_test
	[root@localhost test]# chmod 4775 ~cartaljp/test/suid_test
	[root@localhost test]# exit
	[cartaljp@localhost test]$ cp /bin/ls suid_test
	[cartaljp@localhost test]$ ls -l
	total 72
	-rwsrwxr-x    1 root     cartaljp    67668 Sep 19 07:56 suid_test <-
	Suid bit is still set whereas with 2.4.x kernel it was reset.

Yes. Here 2.4 had the terrible code

     mode = (inode->i_mode & S_IXGRP)*(S_ISGID/S_IXGRP) | S_ISUID;

while 2.6 does things via notify_change().  However, in 2.6 notify_change()
does not allow removal of the SUID bit because you are not owner of the
file :-).  So, we have to convince inode_change_ok() to do it anyway.
parent 829d1232
...@@ -1449,9 +1449,9 @@ void remove_suid(struct dentry *dentry) ...@@ -1449,9 +1449,9 @@ void remove_suid(struct dentry *dentry)
if (!(mode & S_IXGRP)) if (!(mode & S_IXGRP))
mode &= S_ISUID; mode &= S_ISUID;
/* was any of the uid bits set? */ /* were any of the uid bits set? */
if (mode && !capable(CAP_FSETID)) { if (mode && !capable(CAP_FSETID)) {
newattrs.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID; newattrs.ia_valid = ATTR_KILL_SUID|ATTR_KILL_SGID|ATTR_FORCE;
notify_change(dentry, &newattrs); notify_change(dentry, &newattrs);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment