fs: add __remove_file_privs() with flags parameter
This adds the function __remove_file_privs, which allows the caller to pass the kiocb flags parameter. No intended functional changes in this patch. Signed-off-by: Stefan Roesch <shr@fb.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20220623175157.1715274-9-shr@fb.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
8017553980
commit
faf99b5635
1 changed files with 37 additions and 20 deletions
57
fs/inode.c
57
fs/inode.c
|
@ -2010,36 +2010,43 @@ static int __remove_privs(struct user_namespace *mnt_userns,
|
||||||
return notify_change(mnt_userns, dentry, &newattrs, NULL);
|
return notify_change(mnt_userns, dentry, &newattrs, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int __file_remove_privs(struct file *file, unsigned int flags)
|
||||||
* Remove special file priviledges (suid, capabilities) when file is written
|
|
||||||
* to or truncated.
|
|
||||||
*/
|
|
||||||
int file_remove_privs(struct file *file)
|
|
||||||
{
|
{
|
||||||
struct dentry *dentry = file_dentry(file);
|
struct dentry *dentry = file_dentry(file);
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = file_inode(file);
|
||||||
|
int error;
|
||||||
int kill;
|
int kill;
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fast path for nothing security related.
|
|
||||||
* As well for non-regular files, e.g. blkdev inodes.
|
|
||||||
* For example, blkdev_write_iter() might get here
|
|
||||||
* trying to remove privs which it is not allowed to.
|
|
||||||
*/
|
|
||||||
if (IS_NOSEC(inode) || !S_ISREG(inode->i_mode))
|
if (IS_NOSEC(inode) || !S_ISREG(inode->i_mode))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
kill = dentry_needs_remove_privs(dentry);
|
kill = dentry_needs_remove_privs(dentry);
|
||||||
if (kill < 0)
|
if (kill <= 0)
|
||||||
return kill;
|
return kill;
|
||||||
if (kill)
|
|
||||||
error = __remove_privs(file_mnt_user_ns(file), dentry, kill);
|
if (flags & IOCB_NOWAIT)
|
||||||
|
return -EAGAIN;
|
||||||
|
|
||||||
|
error = __remove_privs(file_mnt_user_ns(file), dentry, kill);
|
||||||
if (!error)
|
if (!error)
|
||||||
inode_has_no_xattr(inode);
|
inode_has_no_xattr(inode);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file_remove_privs - remove special file privileges (suid, capabilities)
|
||||||
|
* @file: file to remove privileges from
|
||||||
|
*
|
||||||
|
* When file is modified by a write or truncation ensure that special
|
||||||
|
* file privileges are removed.
|
||||||
|
*
|
||||||
|
* Return: 0 on success, negative errno on failure.
|
||||||
|
*/
|
||||||
|
int file_remove_privs(struct file *file)
|
||||||
|
{
|
||||||
|
return __file_remove_privs(file, 0);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL(file_remove_privs);
|
EXPORT_SYMBOL(file_remove_privs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2090,18 +2097,28 @@ int file_update_time(struct file *file)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(file_update_time);
|
EXPORT_SYMBOL(file_update_time);
|
||||||
|
|
||||||
/* Caller must hold the file's inode lock */
|
/**
|
||||||
|
* file_modified - handle mandated vfs changes when modifying a file
|
||||||
|
* @file: file that was modified
|
||||||
|
*
|
||||||
|
* When file has been modified ensure that special
|
||||||
|
* file privileges are removed and time settings are updated.
|
||||||
|
*
|
||||||
|
* Context: Caller must hold the file's inode lock.
|
||||||
|
*
|
||||||
|
* Return: 0 on success, negative errno on failure.
|
||||||
|
*/
|
||||||
int file_modified(struct file *file)
|
int file_modified(struct file *file)
|
||||||
{
|
{
|
||||||
int err;
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear the security bits if the process is not being run by root.
|
* Clear the security bits if the process is not being run by root.
|
||||||
* This keeps people from modifying setuid and setgid binaries.
|
* This keeps people from modifying setuid and setgid binaries.
|
||||||
*/
|
*/
|
||||||
err = file_remove_privs(file);
|
ret = __file_remove_privs(file, 0);
|
||||||
if (err)
|
if (ret)
|
||||||
return err;
|
return ret;
|
||||||
|
|
||||||
if (unlikely(file->f_mode & FMODE_NOCMTIME))
|
if (unlikely(file->f_mode & FMODE_NOCMTIME))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue