mirror of
https://github.com/joel16/android_kernel_sony_msm8994_rework.git
synced 2025-01-15 05:28:25 +00:00
vfs: splice remove_suid() cleanup
generic_file_splice_write() duplicates remove_suid() just because it doesn't hold i_mutex. But it grabs i_mutex inside splice_from_pipe() anyway, so this is rather pointless. Move locking to generic_file_splice_write() and call remove_suid() and __splice_from_pipe() instead. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
parent
07416d29bc
commit
7f3d4ee108
29
fs/splice.c
29
fs/splice.c
@ -811,24 +811,19 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
|
|||||||
{
|
{
|
||||||
struct address_space *mapping = out->f_mapping;
|
struct address_space *mapping = out->f_mapping;
|
||||||
struct inode *inode = mapping->host;
|
struct inode *inode = mapping->host;
|
||||||
int killsuid, killpriv;
|
struct splice_desc sd = {
|
||||||
|
.total_len = len,
|
||||||
|
.flags = flags,
|
||||||
|
.pos = *ppos,
|
||||||
|
.u.file = out,
|
||||||
|
};
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
killpriv = security_inode_need_killpriv(out->f_path.dentry);
|
inode_double_lock(inode, pipe->inode);
|
||||||
killsuid = should_remove_suid(out->f_path.dentry);
|
ret = remove_suid(out->f_path.dentry);
|
||||||
if (unlikely(killsuid || killpriv)) {
|
if (likely(!ret))
|
||||||
mutex_lock(&inode->i_mutex);
|
ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
|
||||||
if (killpriv)
|
inode_double_unlock(inode, pipe->inode);
|
||||||
err = security_inode_killpriv(out->f_path.dentry);
|
|
||||||
if (!err && killsuid)
|
|
||||||
err = __remove_suid(out->f_path.dentry, killsuid);
|
|
||||||
mutex_unlock(&inode->i_mutex);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
|
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
unsigned long nr_pages;
|
unsigned long nr_pages;
|
||||||
|
|
||||||
@ -840,6 +835,8 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
|
|||||||
* sync it.
|
* sync it.
|
||||||
*/
|
*/
|
||||||
if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
|
if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
|
||||||
|
int err;
|
||||||
|
|
||||||
mutex_lock(&inode->i_mutex);
|
mutex_lock(&inode->i_mutex);
|
||||||
err = generic_osync_inode(inode, mapping,
|
err = generic_osync_inode(inode, mapping,
|
||||||
OSYNC_METADATA|OSYNC_DATA);
|
OSYNC_METADATA|OSYNC_DATA);
|
||||||
|
@ -1816,7 +1816,6 @@ extern void iget_failed(struct inode *);
|
|||||||
extern void clear_inode(struct inode *);
|
extern void clear_inode(struct inode *);
|
||||||
extern void destroy_inode(struct inode *);
|
extern void destroy_inode(struct inode *);
|
||||||
extern struct inode *new_inode(struct super_block *);
|
extern struct inode *new_inode(struct super_block *);
|
||||||
extern int __remove_suid(struct dentry *, int);
|
|
||||||
extern int should_remove_suid(struct dentry *);
|
extern int should_remove_suid(struct dentry *);
|
||||||
extern int remove_suid(struct dentry *);
|
extern int remove_suid(struct dentry *);
|
||||||
|
|
||||||
|
@ -1655,7 +1655,7 @@ int should_remove_suid(struct dentry *dentry)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(should_remove_suid);
|
EXPORT_SYMBOL(should_remove_suid);
|
||||||
|
|
||||||
int __remove_suid(struct dentry *dentry, int kill)
|
static int __remove_suid(struct dentry *dentry, int kill)
|
||||||
{
|
{
|
||||||
struct iattr newattrs;
|
struct iattr newattrs;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user