Merge branch 'splice' of git://brick.kernel.dk/data/git/linux-2.6-block

* 'splice' of git://brick.kernel.dk/data/git/linux-2.6-block:
  [PATCH] Remove SUID when splicing into an inode
  [PATCH] Add lockless helpers for remove_suid()
  [PATCH] Introduce generic_file_splice_write_nolock()
  [PATCH] Take i_mutex in splice_from_pipe()
This commit is contained in:
Linus Torvalds
2006-10-21 10:01:52 -07:00
4 changed files with 148 additions and 30 deletions

View File

@ -1884,11 +1884,10 @@ repeat:
* if suid or (sgid and xgrp)
* remove privs
*/
int remove_suid(struct dentry *dentry)
int should_remove_suid(struct dentry *dentry)
{
mode_t mode = dentry->d_inode->i_mode;
int kill = 0;
int result = 0;
/* suid always must be killed */
if (unlikely(mode & S_ISUID))
@ -1901,13 +1900,28 @@ int remove_suid(struct dentry *dentry)
if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
kill |= ATTR_KILL_SGID;
if (unlikely(kill && !capable(CAP_FSETID))) {
struct iattr newattrs;
if (unlikely(kill && !capable(CAP_FSETID)))
return kill;
newattrs.ia_valid = ATTR_FORCE | kill;
result = notify_change(dentry, &newattrs);
}
return result;
return 0;
}
int __remove_suid(struct dentry *dentry, int kill)
{
struct iattr newattrs;
newattrs.ia_valid = ATTR_FORCE | kill;
return notify_change(dentry, &newattrs);
}
int remove_suid(struct dentry *dentry)
{
int kill = should_remove_suid(dentry);
if (unlikely(kill))
return __remove_suid(dentry, kill);
return 0;
}
EXPORT_SYMBOL(remove_suid);