Commit dbfae0cd authored by Jan Kara's avatar Jan Kara Committed by Al Viro

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: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 5fa8e0a1
...@@ -1673,7 +1673,32 @@ int should_remove_suid(struct dentry *dentry) ...@@ -1673,7 +1673,32 @@ int should_remove_suid(struct dentry *dentry)
} }
EXPORT_SYMBOL(should_remove_suid); EXPORT_SYMBOL(should_remove_suid);
static int __remove_suid(struct dentry *dentry, int kill) /*
* Return mask of changes for notify_change() that need to be done as a
* response to write or truncate. Return 0 if nothing has to be changed.
* Negative value on error (change should be denied).
*/
int file_needs_remove_privs(struct file *file)
{
struct dentry *dentry = file->f_path.dentry;
struct inode *inode = d_inode(dentry);
int mask = 0;
int ret;
if (IS_NOSEC(inode))
return 0;
mask = should_remove_suid(dentry);
ret = security_inode_need_killpriv(dentry);
if (ret < 0)
return ret;
if (ret)
mask |= ATTR_KILL_PRIV;
return mask;
}
EXPORT_SYMBOL(file_needs_remove_privs);
static int __remove_privs(struct dentry *dentry, int kill)
{ {
struct iattr newattrs; struct iattr newattrs;
...@@ -1693,23 +1718,18 @@ int file_remove_privs(struct file *file) ...@@ -1693,23 +1718,18 @@ int file_remove_privs(struct file *file)
{ {
struct dentry *dentry = file->f_path.dentry; struct dentry *dentry = file->f_path.dentry;
struct inode *inode = d_inode(dentry); struct inode *inode = d_inode(dentry);
int killsuid; int kill;
int killpriv;
int error = 0; int error = 0;
/* Fast path for nothing security related */ /* Fast path for nothing security related */
if (IS_NOSEC(inode)) if (IS_NOSEC(inode))
return 0; return 0;
killsuid = should_remove_suid(dentry); kill = file_needs_remove_privs(file);
killpriv = security_inode_need_killpriv(dentry); if (kill < 0)
return kill;
if (killpriv < 0) if (kill)
return killpriv; error = __remove_privs(dentry, kill);
if (killpriv)
error = security_inode_killpriv(dentry);
if (!error && killsuid)
error = __remove_suid(dentry, killsuid);
if (!error) if (!error)
inode_has_no_xattr(inode); inode_has_no_xattr(inode);
......
...@@ -2554,6 +2554,7 @@ extern struct inode *new_inode(struct super_block *sb); ...@@ -2554,6 +2554,7 @@ extern struct inode *new_inode(struct super_block *sb);
extern void free_inode_nonrcu(struct inode *inode); extern void free_inode_nonrcu(struct inode *inode);
extern int should_remove_suid(struct dentry *); extern int should_remove_suid(struct dentry *);
extern int file_remove_privs(struct file *); extern int file_remove_privs(struct file *);
extern int file_needs_remove_privs(struct file *file);
extern void __insert_inode_hash(struct inode *, unsigned long hashval); extern void __insert_inode_hash(struct inode *, unsigned long hashval);
static inline void insert_inode_hash(struct inode *inode) static inline void insert_inode_hash(struct inode *inode)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment