diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2014-01-22 19:36:57 +0100 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2014-04-02 00:58:44 +0100 |
commit | c4047a30fc81715ae56e97f983fd684360fa216c (patch) | |
tree | c81f9236d52e68927410553be65458926d88d7d5 /fs/fuse | |
parent | d43cc1a69f62fe2c261863fc8a8ed9acca57b45f (diff) | |
download | kernel_samsung_smdk4412-c4047a30fc81715ae56e97f983fd684360fa216c.zip kernel_samsung_smdk4412-c4047a30fc81715ae56e97f983fd684360fa216c.tar.gz kernel_samsung_smdk4412-c4047a30fc81715ae56e97f983fd684360fa216c.tar.bz2 |
fuse: fix pipe_buf_operations
commit 28a625cbc2a14f17b83e47ef907b2658576a32aa upstream.
Having this struct in module memory could Oops when if the module is
unloaded while the buffer still persists in a pipe.
Since sock_pipe_buf_ops is essentially the same as fuse_dev_pipe_buf_steal
merge them into nosteal_pipe_buf_ops (this is the same as
default_pipe_buf_ops except stealing the page from the buffer is not
allowed).
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'fs/fuse')
-rw-r--r-- | fs/fuse/dev.c | 22 |
1 files changed, 5 insertions, 17 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 5c029fb..cf0098d 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1199,22 +1199,6 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov, return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs)); } -static int fuse_dev_pipe_buf_steal(struct pipe_inode_info *pipe, - struct pipe_buffer *buf) -{ - return 1; -} - -static const struct pipe_buf_operations fuse_dev_pipe_buf_ops = { - .can_merge = 0, - .map = generic_pipe_buf_map, - .unmap = generic_pipe_buf_unmap, - .confirm = generic_pipe_buf_confirm, - .release = generic_pipe_buf_release, - .steal = fuse_dev_pipe_buf_steal, - .get = generic_pipe_buf_get, -}; - static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags) @@ -1261,7 +1245,11 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, buf->page = bufs[page_nr].page; buf->offset = bufs[page_nr].offset; buf->len = bufs[page_nr].len; - buf->ops = &fuse_dev_pipe_buf_ops; + /* + * Need to be careful about this. Having buf->ops in module + * code can Oops if the buffer persists after module unload. + */ + buf->ops = &nosteal_pipe_buf_ops; pipe->nrbufs++; page_nr++; |