diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-21 13:01:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-21 13:01:52 -0400 |
commit | 7b7fc708b568a258595e1fa911b930a75ac07b48 (patch) | |
tree | 5c77a5397d01c91aaa59ee5517af28afee32afcb /mm/filemap.c | |
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/filemap.c')
-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 8558732e85c1..cb26e33fd0ff 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -1884,11 +1884,10 @@ repeat: | |||
1884 | * if suid or (sgid and xgrp) | 1884 | * if suid or (sgid and xgrp) |
1885 | * remove privs | 1885 | * remove privs |
1886 | */ | 1886 | */ |
1887 | int remove_suid(struct dentry *dentry) | 1887 | int should_remove_suid(struct dentry *dentry) |
1888 | { | 1888 | { |
1889 | mode_t mode = dentry->d_inode->i_mode; | 1889 | mode_t mode = dentry->d_inode->i_mode; |
1890 | int kill = 0; | 1890 | int kill = 0; |
1891 | int result = 0; | ||
1892 | 1891 | ||
1893 | /* suid always must be killed */ | 1892 | /* suid always must be killed */ |
1894 | if (unlikely(mode & S_ISUID)) | 1893 | if (unlikely(mode & S_ISUID)) |
@@ -1901,13 +1900,28 @@ int remove_suid(struct dentry *dentry) | |||
1901 | if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) | 1900 | if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) |
1902 | kill |= ATTR_KILL_SGID; | 1901 | kill |= ATTR_KILL_SGID; |
1903 | 1902 | ||
1904 | if (unlikely(kill && !capable(CAP_FSETID))) { | 1903 | if (unlikely(kill && !capable(CAP_FSETID))) |
1905 | struct iattr newattrs; | 1904 | return kill; |
1906 | 1905 | ||
1907 | newattrs.ia_valid = ATTR_FORCE | kill; | 1906 | return 0; |
1908 | result = notify_change(dentry, &newattrs); | 1907 | } |
1909 | } | 1908 | |
1910 | return result; | 1909 | int __remove_suid(struct dentry *dentry, int kill) |
1910 | { | ||
1911 | struct iattr newattrs; | ||
1912 | |||
1913 | newattrs.ia_valid = ATTR_FORCE | kill; | ||
1914 | return notify_change(dentry, &newattrs); | ||
1915 | } | ||
1916 | |||
1917 | int remove_suid(struct dentry *dentry) | ||
1918 | { | ||
1919 | int kill = should_remove_suid(dentry); | ||
1920 | |||
1921 | if (unlikely(kill)) | ||
1922 | return __remove_suid(dentry, kill); | ||
1923 | |||
1924 | return 0; | ||
1911 | } | 1925 | } |
1912 | EXPORT_SYMBOL(remove_suid); | 1926 | EXPORT_SYMBOL(remove_suid); |
1913 | 1927 | ||