diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-21 10:01:52 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-21 10:01:52 -0700 |
commit | 7b7fc708b568a258595e1fa911b930a75ac07b48 (patch) | |
tree | 5c77a5397d01c91aaa59ee5517af28afee32afcb /mm | |
parent | c7a3bd177f248d01ee18a01d22048c80e071c331 (diff) | |
parent | 8c34e2d63231d4bf4852bac8521883944d770fe3 (diff) |
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()
Diffstat (limited to 'mm')
-rw-r--r-- | mm/filemap.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 8558732e85c..cb26e33fd0f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -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); |