summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2014-01-22 13:36:57 -0500
committerMiklos Szeredi <mszeredi@suse.cz>2014-01-22 13:36:57 -0500
commit28a625cbc2a14f17b83e47ef907b2658576a32aa (patch)
tree58d461b91f25a6499bd6404cd79faa4f9c185ff0
parentd8ec26d7f8287f5788a494f56e8814210f0e64be (diff)
fuse: fix pipe_buf_operations
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> Cc: stable@vger.kernel.org
-rw-r--r--fs/fuse/dev.c22
-rw-r--r--fs/splice.c18
-rw-r--r--include/linux/pipe_fs_i.h2
-rw-r--r--net/core/skbuff.c32
4 files changed, 26 insertions, 48 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index ef74ad5fd362..fa8cb4b7b8fe 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1296,22 +1296,6 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
1296 return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs)); 1296 return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs));
1297} 1297}
1298 1298
1299static int fuse_dev_pipe_buf_steal(struct pipe_inode_info *pipe,
1300 struct pipe_buffer *buf)
1301{
1302 return 1;
1303}
1304
1305static const struct pipe_buf_operations fuse_dev_pipe_buf_ops = {
1306 .can_merge = 0,
1307 .map = generic_pipe_buf_map,
1308 .unmap = generic_pipe_buf_unmap,
1309 .confirm = generic_pipe_buf_confirm,
1310 .release = generic_pipe_buf_release,
1311 .steal = fuse_dev_pipe_buf_steal,
1312 .get = generic_pipe_buf_get,
1313};
1314
1315static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, 1299static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
1316 struct pipe_inode_info *pipe, 1300 struct pipe_inode_info *pipe,
1317 size_t len, unsigned int flags) 1301 size_t len, unsigned int flags)
@@ -1358,7 +1342,11 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
1358 buf->page = bufs[page_nr].page; 1342 buf->page = bufs[page_nr].page;
1359 buf->offset = bufs[page_nr].offset; 1343 buf->offset = bufs[page_nr].offset;
1360 buf->len = bufs[page_nr].len; 1344 buf->len = bufs[page_nr].len;
1361 buf->ops = &fuse_dev_pipe_buf_ops; 1345 /*
1346 * Need to be careful about this. Having buf->ops in module
1347 * code can Oops if the buffer persists after module unload.
1348 */
1349 buf->ops = &nosteal_pipe_buf_ops;
1362 1350
1363 pipe->nrbufs++; 1351 pipe->nrbufs++;
1364 page_nr++; 1352 page_nr++;
diff --git a/fs/splice.c b/fs/splice.c
index 46a08f772d7d..12028fa41def 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -555,6 +555,24 @@ static const struct pipe_buf_operations default_pipe_buf_ops = {
555 .get = generic_pipe_buf_get, 555 .get = generic_pipe_buf_get,
556}; 556};
557 557
558static int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe,
559 struct pipe_buffer *buf)
560{
561 return 1;
562}
563
564/* Pipe buffer operations for a socket and similar. */
565const struct pipe_buf_operations nosteal_pipe_buf_ops = {
566 .can_merge = 0,
567 .map = generic_pipe_buf_map,
568 .unmap = generic_pipe_buf_unmap,
569 .confirm = generic_pipe_buf_confirm,
570 .release = generic_pipe_buf_release,
571 .steal = generic_pipe_buf_nosteal,
572 .get = generic_pipe_buf_get,
573};
574EXPORT_SYMBOL(nosteal_pipe_buf_ops);
575
558static ssize_t kernel_readv(struct file *file, const struct iovec *vec, 576static ssize_t kernel_readv(struct file *file, const struct iovec *vec,
559 unsigned long vlen, loff_t offset) 577 unsigned long vlen, loff_t offset)
560{ 578{
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index b8809fef61f5..ab5752692113 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -157,6 +157,8 @@ int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *);
157int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); 157int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
158void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *); 158void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
159 159
160extern const struct pipe_buf_operations nosteal_pipe_buf_ops;
161
160/* for F_SETPIPE_SZ and F_GETPIPE_SZ */ 162/* for F_SETPIPE_SZ and F_GETPIPE_SZ */
161long pipe_fcntl(struct file *, unsigned int, unsigned long arg); 163long pipe_fcntl(struct file *, unsigned int, unsigned long arg);
162struct pipe_inode_info *get_pipe_info(struct file *file); 164struct pipe_inode_info *get_pipe_info(struct file *file);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 06e72d3cdf60..0b5149c5bc4a 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -74,36 +74,6 @@
74struct kmem_cache *skbuff_head_cache __read_mostly; 74struct kmem_cache *skbuff_head_cache __read_mostly;
75static struct kmem_cache *skbuff_fclone_cache __read_mostly; 75static struct kmem_cache *skbuff_fclone_cache __read_mostly;
76 76
77static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
78 struct pipe_buffer *buf)
79{
80 put_page(buf->page);
81}
82
83static void sock_pipe_buf_get(struct pipe_inode_info *pipe,
84 struct pipe_buffer *buf)
85{
86 get_page(buf->page);
87}
88
89static int sock_pipe_buf_steal(struct pipe_inode_info *pipe,
90 struct pipe_buffer *buf)
91{
92 return 1;
93}
94
95
96/* Pipe buffer operations for a socket. */
97static const struct pipe_buf_operations sock_pipe_buf_ops = {
98 .can_merge = 0,
99 .map = generic_pipe_buf_map,
100 .unmap = generic_pipe_buf_unmap,
101 .confirm = generic_pipe_buf_confirm,
102 .release = sock_pipe_buf_release,
103 .steal = sock_pipe_buf_steal,
104 .get = sock_pipe_buf_get,
105};
106
107/** 77/**
108 * skb_panic - private function for out-of-line support 78 * skb_panic - private function for out-of-line support
109 * @skb: buffer 79 * @skb: buffer
@@ -1830,7 +1800,7 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
1830 .partial = partial, 1800 .partial = partial,
1831 .nr_pages_max = MAX_SKB_FRAGS, 1801 .nr_pages_max = MAX_SKB_FRAGS,
1832 .flags = flags, 1802 .flags = flags,
1833 .ops = &sock_pipe_buf_ops, 1803 .ops = &nosteal_pipe_buf_ops,
1834 .spd_release = sock_spd_release, 1804 .spd_release = sock_spd_release,
1835 }; 1805 };
1836 struct sk_buff *frag_iter; 1806 struct sk_buff *frag_iter;