diff mbox series

[net] gre: fix kernel panic when using lw tunnel

Message ID 20190306103227.21279-1-nicolas.dichtel@6wind.com
State Superseded
Delegated to: David Miller
Headers show
Series [net] gre: fix kernel panic when using lw tunnel | expand

Commit Message

Nicolas Dichtel March 6, 2019, 10:32 a.m. UTC
There was several problems:
 - skb_dst(skb) can be NULL when the packet comes from a gretap tunnel;
 - skb_dst(skb)->ops may point to md_dst_ops, which doesn't set ->mtu
   handler, thus calling dst_mtu() leads to a panic.

I also wonder if ->cow_metrics may be called if skb_dst(skb)->ops points
to ovs_dst_ops.

Don't try to do anything in one of those cases.

Fixes: 962924fa2b7a ("ip_gre: Refactor collect metatdata mode tunnel xmit to ip_md_tunnel_xmit")
CC: wenxu <wenxu@ucloud.cn>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 net/ipv4/ip_tunnel.c | 6 ++++++
 1 file changed, 6 insertions(+)

Comments

Nicolas Dichtel March 6, 2019, 1:55 p.m. UTC | #1
Le 06/03/2019 à 11:32, Nicolas Dichtel a écrit :
> There was several problems:
>  - skb_dst(skb) can be NULL when the packet comes from a gretap tunnel;
>  - skb_dst(skb)->ops may point to md_dst_ops, which doesn't set ->mtu
>    handler, thus calling dst_mtu() leads to a panic.
> 
> I also wonder if ->cow_metrics may be called if skb_dst(skb)->ops points
> to ovs_dst_ops.
> 
> Don't try to do anything in one of those cases.
> 
> Fixes: 962924fa2b7a ("ip_gre: Refactor collect metatdata mode tunnel xmit to ip_md_tunnel_xmit")
> CC: wenxu <wenxu@ucloud.cn>
> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Please, drop it, Alan's version is better.


Regards,
Nicolas
diff mbox series

Patch

diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 2756fb725bf0..e2e0e4601c0f 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -508,6 +508,12 @@  static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
 	int pkt_size;
 	int mtu;
 
+	if (!skb_dst(skb) ||
+	    !skb_dst(skb)->ops->mtu ||
+	    (dst_metrics_read_only(skb_dst(skb)) &&
+	     !skb_dst(skb)->ops->cow_metrics))
+		return 0;
+
 	tunnel_hlen = md ? tunnel_hlen : tunnel->hlen;
 	pkt_size = skb->len - tunnel_hlen - dev->hard_header_len;