Message ID | 8aaf175761cb492fe484932053d5e4b2f3e0bb89.1554388480.git.lorenzo.bianconi@redhat.com |
---|---|
State | Accepted |
Delegated to: | David Miller |
Headers | show |
Series | [net] ipv6: sit: reset ip header pointer in ipip6_rcv | expand |
From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> Date: Thu, 4 Apr 2019 16:37:53 +0200 > ipip6 tunnels run iptunnel_pull_header on received skbs. This can > determine the following use-after-free accessing iph pointer since > the packet will be 'uncloned' running pskb_expand_head if it is a > cloned gso skb (e.g if the packet has been sent though a veth device) ... > Fix it resetting iph pointer after iptunnel_pull_header > > Fixes: a09a4c8dd1ec ("tunnels: Remove encapsulation offloads on decap") > Tested-by: Jianlin Shi <jishi@redhat.com> > Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> Good catch, applied, thanks.
> From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> > Date: Thu, 4 Apr 2019 16:37:53 +0200 > > > ipip6 tunnels run iptunnel_pull_header on received skbs. This can > > determine the following use-after-free accessing iph pointer since > > the packet will be 'uncloned' running pskb_expand_head if it is a > > cloned gso skb (e.g if the packet has been sent though a veth device) > ... > > Fix it resetting iph pointer after iptunnel_pull_header > > > > Fixes: a09a4c8dd1ec ("tunnels: Remove encapsulation offloads on decap") > > Tested-by: Jianlin Shi <jishi@redhat.com> > > Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> > > Good catch, applied, thanks. looking at the code it seems there is the same issue for erspan_v{4,6}. I will post a fix soon. Regards, Lorenzo
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 07e21a82ce4c..b2109b74857d 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -669,6 +669,10 @@ static int ipip6_rcv(struct sk_buff *skb) !net_eq(tunnel->net, dev_net(tunnel->dev)))) goto out; + /* skb can be uncloned in iptunnel_pull_header, so + * old iph is no longer valid + */ + iph = (const struct iphdr *)skb_mac_header(skb); err = IP_ECN_decapsulate(iph, skb); if (unlikely(err)) { if (log_ecn_error)