|
@@ -1938,71 +1938,6 @@ struct page *read_cache_page(struct address_space *mapping,
|
|
|
}
|
|
|
EXPORT_SYMBOL(read_cache_page);
|
|
|
|
|
|
-/*
|
|
|
- * The logic we want is
|
|
|
- *
|
|
|
- * if suid or (sgid and xgrp)
|
|
|
- * remove privs
|
|
|
- */
|
|
|
-int should_remove_suid(struct dentry *dentry)
|
|
|
-{
|
|
|
- umode_t mode = dentry->d_inode->i_mode;
|
|
|
- int kill = 0;
|
|
|
-
|
|
|
- /* suid always must be killed */
|
|
|
- if (unlikely(mode & S_ISUID))
|
|
|
- kill = ATTR_KILL_SUID;
|
|
|
-
|
|
|
- /*
|
|
|
- * sgid without any exec bits is just a mandatory locking mark; leave
|
|
|
- * it alone. If some exec bits are set, it's a real sgid; kill it.
|
|
|
- */
|
|
|
- if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
|
|
|
- kill |= ATTR_KILL_SGID;
|
|
|
-
|
|
|
- if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))
|
|
|
- return kill;
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-EXPORT_SYMBOL(should_remove_suid);
|
|
|
-
|
|
|
-static int __remove_suid(struct dentry *dentry, int kill)
|
|
|
-{
|
|
|
- struct iattr newattrs;
|
|
|
-
|
|
|
- newattrs.ia_valid = ATTR_FORCE | kill;
|
|
|
- return notify_change(dentry, &newattrs);
|
|
|
-}
|
|
|
-
|
|
|
-int file_remove_suid(struct file *file)
|
|
|
-{
|
|
|
- struct dentry *dentry = file->f_path.dentry;
|
|
|
- struct inode *inode = dentry->d_inode;
|
|
|
- int killsuid;
|
|
|
- int killpriv;
|
|
|
- int error = 0;
|
|
|
-
|
|
|
- /* Fast path for nothing security related */
|
|
|
- if (IS_NOSEC(inode))
|
|
|
- return 0;
|
|
|
-
|
|
|
- killsuid = should_remove_suid(dentry);
|
|
|
- killpriv = security_inode_need_killpriv(dentry);
|
|
|
-
|
|
|
- if (killpriv < 0)
|
|
|
- return killpriv;
|
|
|
- if (killpriv)
|
|
|
- error = security_inode_killpriv(dentry);
|
|
|
- if (!error && killsuid)
|
|
|
- error = __remove_suid(dentry, killsuid);
|
|
|
- if (!error && (inode->i_sb->s_flags & MS_NOSEC))
|
|
|
- inode->i_flags |= S_NOSEC;
|
|
|
-
|
|
|
- return error;
|
|
|
-}
|
|
|
-EXPORT_SYMBOL(file_remove_suid);
|
|
|
-
|
|
|
static size_t __iovec_copy_from_user_inatomic(char *vaddr,
|
|
|
const struct iovec *iov, size_t base, size_t bytes)
|
|
|
{
|