Message ID | 20200330165129.5200-1-fw@strlen.de |
---|---|
State | Accepted |
Delegated to: | David Miller |
Headers | show |
Series | [net,1/1] net: fix fraglist segmentation reference count leak | expand |
On Mon, Mar 30, 2020 at 06:51:29PM +0200, Florian Westphal wrote: > Xin Long says: > On udp rx path udp_rcv_segment() may do segment where the frag skbs > will get the header copied from the head skb in skb_segment_list() > by calling __copy_skb_header(), which could overwrite the frag skbs' > extensions by __skb_ext_copy() and cause a leak. > > This issue was found after loading esp_offload where a sec path ext > is set in the skb. > > Fix this by discarding head state of the fraglist skb before replacing > its contents. > > Fixes: 3a1296a38d0cf62 ("net: Support GRO/GSO fraglist chaining.") > Cc: Steffen Klassert <steffen.klassert@secunet.com> > Reported-by: Xiumei Mu <xmu@redhat.com> > Tested-by: Xin Long <lucien.xin@gmail.com> > Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Steffen Klassert <steffen.klassert@secunet.com>
From: Florian Westphal <fw@strlen.de> Date: Mon, 30 Mar 2020 18:51:29 +0200 > Xin Long says: > On udp rx path udp_rcv_segment() may do segment where the frag skbs > will get the header copied from the head skb in skb_segment_list() > by calling __copy_skb_header(), which could overwrite the frag skbs' > extensions by __skb_ext_copy() and cause a leak. > > This issue was found after loading esp_offload where a sec path ext > is set in the skb. > > Fix this by discarding head state of the fraglist skb before replacing > its contents. > > Fixes: 3a1296a38d0cf62 ("net: Support GRO/GSO fraglist chaining.") > Cc: Steffen Klassert <steffen.klassert@secunet.com> > Reported-by: Xiumei Mu <xmu@redhat.com> > Tested-by: Xin Long <lucien.xin@gmail.com> > Signed-off-by: Florian Westphal <fw@strlen.de> Applied and queued up for v5.6 -stable, thanks.
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index e1101a4f90a6..bea447f38dcc 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3668,6 +3668,7 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb, skb_push(nskb, -skb_network_offset(nskb) + offset); + skb_release_head_state(nskb); __copy_skb_header(nskb, skb); skb_headers_offset_update(nskb, skb_headroom(nskb) - skb_headroom(skb));