diff options
author | Jan Kara <jack@suse.cz> | 2015-05-21 10:05:54 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-06-23 18:01:09 -0400 |
commit | dbfae0cdcd87602737101d4417811f4323156b54 (patch) | |
tree | be947840a5adb296619ebd75898740de16ded617 | |
parent | 5fa8e0a1c6a762857ae67d1628c58b9a02362003 (diff) |
fs: Provide function telling whether file_remove_privs() will do anything
Provide function telling whether file_remove_privs() will do anything.
Currently we only have should_remove_suid() and that does something
slightly different.
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/inode.c | 44 | ||||
-rw-r--r-- | include/linux/fs.h | 1 |
2 files changed, 33 insertions, 12 deletions
diff --git a/fs/inode.c b/fs/inode.c index 849210c155dc..8c2dd74455c9 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -1673,7 +1673,32 @@ int should_remove_suid(struct dentry *dentry) | |||
1673 | } | 1673 | } |
1674 | EXPORT_SYMBOL(should_remove_suid); | 1674 | EXPORT_SYMBOL(should_remove_suid); |
1675 | 1675 | ||
1676 | static int __remove_suid(struct dentry *dentry, int kill) | 1676 | /* |
1677 | * Return mask of changes for notify_change() that need to be done as a | ||
1678 | * response to write or truncate. Return 0 if nothing has to be changed. | ||
1679 | * Negative value on error (change should be denied). | ||
1680 | */ | ||
1681 | int file_needs_remove_privs(struct file *file) | ||
1682 | { | ||
1683 | struct dentry *dentry = file->f_path.dentry; | ||
1684 | struct inode *inode = d_inode(dentry); | ||
1685 | int mask = 0; | ||
1686 | int ret; | ||
1687 | |||
1688 | if (IS_NOSEC(inode)) | ||
1689 | return 0; | ||
1690 | |||
1691 | mask = should_remove_suid(dentry); | ||
1692 | ret = security_inode_need_killpriv(dentry); | ||
1693 | if (ret < 0) | ||
1694 | return ret; | ||
1695 | if (ret) | ||
1696 | mask |= ATTR_KILL_PRIV; | ||
1697 | return mask; | ||
1698 | } | ||
1699 | EXPORT_SYMBOL(file_needs_remove_privs); | ||
1700 | |||
1701 | static int __remove_privs(struct dentry *dentry, int kill) | ||
1677 | { | 1702 | { |
1678 | struct iattr newattrs; | 1703 | struct iattr newattrs; |
1679 | 1704 | ||
@@ -1693,23 +1718,18 @@ int file_remove_privs(struct file *file) | |||
1693 | { | 1718 | { |
1694 | struct dentry *dentry = file->f_path.dentry; | 1719 | struct dentry *dentry = file->f_path.dentry; |
1695 | struct inode *inode = d_inode(dentry); | 1720 | struct inode *inode = d_inode(dentry); |
1696 | int killsuid; | 1721 | int kill; |
1697 | int killpriv; | ||
1698 | int error = 0; | 1722 | int error = 0; |
1699 | 1723 | ||
1700 | /* Fast path for nothing security related */ | 1724 | /* Fast path for nothing security related */ |
1701 | if (IS_NOSEC(inode)) | 1725 | if (IS_NOSEC(inode)) |
1702 | return 0; | 1726 | return 0; |
1703 | 1727 | ||
1704 | killsuid = should_remove_suid(dentry); | 1728 | kill = file_needs_remove_privs(file); |
1705 | killpriv = security_inode_need_killpriv(dentry); | 1729 | if (kill < 0) |
1706 | 1730 | return kill; | |
1707 | if (killpriv < 0) | 1731 | if (kill) |
1708 | return killpriv; | 1732 | error = __remove_privs(dentry, kill); |
1709 | if (killpriv) | ||
1710 | error = security_inode_killpriv(dentry); | ||
1711 | if (!error && killsuid) | ||
1712 | error = __remove_suid(dentry, killsuid); | ||
1713 | if (!error) | 1733 | if (!error) |
1714 | inode_has_no_xattr(inode); | 1734 | inode_has_no_xattr(inode); |
1715 | 1735 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 641e68d850cf..ee60e8ab210f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -2554,6 +2554,7 @@ extern struct inode *new_inode(struct super_block *sb); | |||
2554 | extern void free_inode_nonrcu(struct inode *inode); | 2554 | extern void free_inode_nonrcu(struct inode *inode); |
2555 | extern int should_remove_suid(struct dentry *); | 2555 | extern int should_remove_suid(struct dentry *); |
2556 | extern int file_remove_privs(struct file *); | 2556 | extern int file_remove_privs(struct file *); |
2557 | extern int file_needs_remove_privs(struct file *file); | ||
2557 | 2558 | ||
2558 | extern void __insert_inode_hash(struct inode *, unsigned long hashval); | 2559 | extern void __insert_inode_hash(struct inode *, unsigned long hashval); |
2559 | static inline void insert_inode_hash(struct inode *inode) | 2560 | static inline void insert_inode_hash(struct inode *inode) |