diff mbox

[3.2-3.12] skbuff: skb_segment: orphan frags before copying

Message ID 1397429860.10849.86.camel@deadeye.wl.decadent.org.uk
State Not Applicable, archived
Delegated to: David Miller
Headers show

Commit Message

Ben Hutchings April 13, 2014, 10:57 p.m. UTC
From: "Michael S. Tsirkin" <mst@redhat.com>

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>
---
For branches older than 3.6, commit a353e0ce0fd4 ('skbuff: add an api to
orphan frags') is needed before this.  This is untested and I would
appreciate a review.

Ben.
---

Comments

David Miller April 13, 2014, 11:20 p.m. UTC | #1
From: Ben Hutchings <ben@decadent.org.uk>
Date: Sun, 13 Apr 2014 23:57:40 +0100

> From: "Michael S. Tsirkin" <mst@redhat.com>
> 
> 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>
> ---
> For branches older than 3.6, commit a353e0ce0fd4 ('skbuff: add an api to
> orphan frags') is needed before this.  This is untested and I would
> appreciate a review.

I didn't do this backport because it seemed risky unless Michael
or someone else tested it thoroughly.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ben Hutchings April 13, 2014, 11:50 p.m. UTC | #2
On Sun, 2014-04-13 at 19:20 -0400, David Miller wrote:
> From: Ben Hutchings <ben@decadent.org.uk>
> Date: Sun, 13 Apr 2014 23:57:40 +0100
> 
> > From: "Michael S. Tsirkin" <mst@redhat.com>
> > 
> > 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>
> > ---
> > For branches older than 3.6, commit a353e0ce0fd4 ('skbuff: add an api to
> > orphan frags') is needed before this.  This is untested and I would
> > appreciate a review.
> 
> I didn't do this backport because it seemed risky unless Michael
> or someone else tested it thoroughly.

Understood; I'll wait for further feedback.

Ben.
diff mbox

Patch

--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2699,6 +2699,9 @@  struct sk_buff *skb_segment(struct sk_bu
 						 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);