aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/inode.c65
-rw-r--r--mm/filemap.c65
2 files changed, 65 insertions, 65 deletions
diff --git a/fs/inode.c b/fs/inode.c
index 183ddd6cda71..a79555e492e0 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1530,6 +1530,71 @@ void touch_atime(struct path *path)
1530} 1530}
1531EXPORT_SYMBOL(touch_atime); 1531EXPORT_SYMBOL(touch_atime);
1532 1532
1533/*
1534 * The logic we want is
1535 *
1536 * if suid or (sgid and xgrp)
1537 * remove privs
1538 */
1539int should_remove_suid(struct dentry *dentry)
1540{
1541 umode_t mode = dentry->d_inode->i_mode;
1542 int kill = 0;
1543
1544 /* suid always must be killed */
1545 if (unlikely(mode & S_ISUID))
1546 kill = ATTR_KILL_SUID;
1547
1548 /*
1549 * sgid without any exec bits is just a mandatory locking mark; leave
1550 * it alone. If some exec bits are set, it's a real sgid; kill it.
1551 */
1552 if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
1553 kill |= ATTR_KILL_SGID;
1554
1555 if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))
1556 return kill;
1557
1558 return 0;
1559}
1560EXPORT_SYMBOL(should_remove_suid);
1561
1562static int __remove_suid(struct dentry *dentry, int kill)
1563{
1564 struct iattr newattrs;
1565
1566 newattrs.ia_valid = ATTR_FORCE | kill;
1567 return notify_change(dentry, &newattrs);
1568}
1569
1570int file_remove_suid(struct file *file)
1571{
1572 struct dentry *dentry = file->f_path.dentry;
1573 struct inode *inode = dentry->d_inode;
1574 int killsuid;
1575 int killpriv;
1576 int error = 0;
1577
1578 /* Fast path for nothing security related */
1579 if (IS_NOSEC(inode))
1580 return 0;
1581
1582 killsuid = should_remove_suid(dentry);
1583 killpriv = security_inode_need_killpriv(dentry);
1584
1585 if (killpriv < 0)
1586 return killpriv;
1587 if (killpriv)
1588 error = security_inode_killpriv(dentry);
1589 if (!error && killsuid)
1590 error = __remove_suid(dentry, killsuid);
1591 if (!error && (inode->i_sb->s_flags & MS_NOSEC))
1592 inode->i_flags |= S_NOSEC;
1593
1594 return error;
1595}
1596EXPORT_SYMBOL(file_remove_suid);
1597
1533/** 1598/**
1534 * file_update_time - update mtime and ctime time 1599 * file_update_time - update mtime and ctime time
1535 * @file: file accessed 1600 * @file: file accessed
diff --git a/mm/filemap.c b/mm/filemap.c
index 79c4b2b0b14e..21e5abfbcdf6 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1938,71 +1938,6 @@ struct page *read_cache_page(struct address_space *mapping,
1938} 1938}
1939EXPORT_SYMBOL(read_cache_page); 1939EXPORT_SYMBOL(read_cache_page);
1940 1940
1941/*
1942 * The logic we want is
1943 *
1944 * if suid or (sgid and xgrp)
1945 * remove privs
1946 */
1947int should_remove_suid(struct dentry *dentry)
1948{
1949 umode_t mode = dentry->d_inode->i_mode;
1950 int kill = 0;
1951
1952 /* suid always must be killed */
1953 if (unlikely(mode & S_ISUID))
1954 kill = ATTR_KILL_SUID;
1955
1956 /*
1957 * sgid without any exec bits is just a mandatory locking mark; leave
1958 * it alone. If some exec bits are set, it's a real sgid; kill it.
1959 */
1960 if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
1961 kill |= ATTR_KILL_SGID;
1962
1963 if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))
1964 return kill;
1965
1966 return 0;
1967}
1968EXPORT_SYMBOL(should_remove_suid);
1969
1970static int __remove_suid(struct dentry *dentry, int kill)
1971{
1972 struct iattr newattrs;
1973
1974 newattrs.ia_valid = ATTR_FORCE | kill;
1975 return notify_change(dentry, &newattrs);
1976}
1977
1978int file_remove_suid(struct file *file)
1979{
1980 struct dentry *dentry = file->f_path.dentry;
1981 struct inode *inode = dentry->d_inode;
1982 int killsuid;
1983 int killpriv;
1984 int error = 0;
1985
1986 /* Fast path for nothing security related */
1987 if (IS_NOSEC(inode))
1988 return 0;
1989
1990 killsuid = should_remove_suid(dentry);
1991 killpriv = security_inode_need_killpriv(dentry);
1992
1993 if (killpriv < 0)
1994 return killpriv;
1995 if (killpriv)
1996 error = security_inode_killpriv(dentry);
1997 if (!error && killsuid)
1998 error = __remove_suid(dentry, killsuid);
1999 if (!error && (inode->i_sb->s_flags & MS_NOSEC))
2000 inode->i_flags |= S_NOSEC;
2001
2002 return error;
2003}
2004EXPORT_SYMBOL(file_remove_suid);
2005
2006static size_t __iovec_copy_from_user_inatomic(char *vaddr, 1941static size_t __iovec_copy_from_user_inatomic(char *vaddr,
2007 const struct iovec *iov, size_t base, size_t bytes) 1942 const struct iovec *iov, size_t base, size_t bytes)
2008{ 1943{