aboutsummaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-06-12 15:24:40 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-16 09:04:42 -0700
commit2c07f25ea7800adb36cd8da9b58c4ecd3fc3d064 (patch)
treeb312e3b679b544de20569f8e31dd1469e8a72be1 /net/core
parent5318edefb61eddf91d4c4a089644fcee3ccfda62 (diff)
splice: fix racy pipe->buffers uses
commit 047fe3605235888f3ebcda0c728cb31937eadfe6 upstream. Dave Jones reported a kernel BUG at mm/slub.c:3474! triggered by splice_shrink_spd() called from vmsplice_to_pipe() commit 35f3d14dbbc5 (pipe: add support for shrinking and growing pipes) added capability to adjust pipe->buffers. Problem is some paths don't hold pipe mutex and assume pipe->buffers doesn't change for their duration. Fix this by adding nr_pages_max field in struct splice_pipe_desc, and use it in place of pipe->buffers where appropriate. splice_shrink_spd() loses its struct pipe_inode_info argument. Reported-by: Dave Jones <davej@redhat.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Jens Axboe <axboe@kernel.dk> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: Tom Herbert <therbert@google.com> Tested-by: Dave Jones <davej@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk> [bwh: Backported to 3.2: - Adjust context in vmsplice_to_pipe() - Update one more call to splice_shrink_spd(), from skb_splice_bits()] Signed-off-by: Ben Hutchings <ben@decadent.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/skbuff.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index e59840010d4..e99aedd9c49 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1712,6 +1712,7 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
struct splice_pipe_desc spd = {
.pages = pages,
.partial = partial,
+ .nr_pages_max = MAX_SKB_FRAGS,
.flags = flags,
.ops = &sock_pipe_buf_ops,
.spd_release = sock_spd_release,
@@ -1758,7 +1759,7 @@ done:
lock_sock(sk);
}
- splice_shrink_spd(pipe, &spd);
+ splice_shrink_spd(&spd);
return ret;
}