Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+32 −12
Original line number Diff line number Diff line
@@ -1673,7 +1673,32 @@ int should_remove_suid(struct dentry *dentry)
}
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;

@@ -1693,23 +1718,18 @@ int file_remove_privs(struct file *file)
{
	struct dentry *dentry = file->f_path.dentry;
	struct inode *inode = d_inode(dentry);
	int killsuid;
	int killpriv;
	int kill;
	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);
	kill = file_needs_remove_privs(file);
	if (kill < 0)
		return kill;
	if (kill)
		error = __remove_privs(dentry, kill);
	if (!error)
		inode_has_no_xattr(inode);

+1 −0
Original line number Diff line number Diff line
@@ -2554,6 +2554,7 @@ extern struct inode *new_inode(struct super_block *sb);
extern void free_inode_nonrcu(struct inode *inode);
extern int should_remove_suid(struct dentry *);
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);
static inline void insert_inode_hash(struct inode *inode)