summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2014-03-10 19:28:08 +0200
committerBen Hutchings <ben@decadent.org.uk>2014-07-11 13:34:00 +0100
commit77c01a54cde87eb3bf6685fb44398352f11db3fa (patch)
tree6444e61b89e26e82bec2969ea02d34982091f2b3
parent3ee479fddc52bbcb3b215be56673e9784890b486 (diff)
skbuff: skb_segment: orphan frags before copying
commit 1fd819ecb90cc9b822cd84d3056ddba315d3340f upstream. skb_segment copies frags around, so we need to copy them carefully to avoid accessing user memory after reporting completion to userspace through a callback. skb_segment doesn't normally happen on datapath: TSO needs to be disabled - so disabling zero copy in this case does not look like a big deal. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Acked-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net> [bwh: Backported to 3.2. As skb_segment() only supports page-frags *or* a frag list, there is no need for the additional frag_skb pointer or the preparatory renaming.] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--net/core/skbuff.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index e6289b474fe2..7121d9b59bbd 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2698,6 +2698,9 @@ struct sk_buff *skb_segment(struct sk_buff *skb, u32 features)
skb_put(nskb, hsize), hsize);
while (pos < offset + len && i < nfrags) {
+ if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC)))
+ goto err;
+
*frag = skb_shinfo(skb)->frags[i];
__skb_frag_ref(frag);
size = skb_frag_size(frag);