[ovs-dev] [PATCH] ip_tunnel: Fix bugs that could crash kernel

Yifeng Sun pkusunyifeng at gmail.com
Fri Jul 20 18:04:42 UTC 2018


Without this patch, OVS kernel module can delete itn->fb_tunnel_dev
one more time than necessary, which causes kernel crash.

On kernel 4.4.0-116-generic, the crash can be reproduced by running
the simple test provided below through check-kernel.

  make & make modules_install
  rmmod ip_gre gre ip_tunnel
  modprobe openvswitch
  make check-kernel TESTSUITEFLAGS=x
  dmesg

Simple test:

AT_SETUP([datapath - crash test])                                              
OVS_CHECK_GRE()                                                                
ip link del gre0                                                               
OVS_TRAFFIC_VSWITCHD_START()                                                    
AT_CHECK([ovs-vsctl -- set bridge br0])                                        
ADD_BR([br-underlay], [set bridge br-underlay])                                
AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])                            
AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"])                    
ADD_NAMESPACES(at_ns0)                                                         
ADD_VETH(p0, at_ns0, br-underlay, "172.31.1.1/24")                             
AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"])                      
AT_CHECK([ip link set dev br-underlay up])                                     
ADD_OVS_TUNNEL([gre], [br0], [at_gre0], [172.31.1.1], [10.1.1.100/24])         
tcpdump -U -i br-underlay -w underlay.pcap &                                   
sleep 1                                                                         
OVS_TRAFFIC_VSWITCHD_STOP                                                      
AT_CLEANUP

Signed-off-by: Yifeng Sun <pkusunyifeng at gmail.com>
---
 datapath/linux/compat/ip_tunnel.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/datapath/linux/compat/ip_tunnel.c b/datapath/linux/compat/ip_tunnel.c
index 54af1f178d36..d16e60fbfef0 100644
--- a/datapath/linux/compat/ip_tunnel.c
+++ b/datapath/linux/compat/ip_tunnel.c
@@ -482,8 +482,10 @@ void rpl_ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
 
 	itn = net_generic(tunnel->net, tunnel->ip_tnl_net_id);
 
-	ip_tunnel_del(itn, netdev_priv(dev));
-        unregister_netdevice_queue(dev, head);
+	if (itn->fb_tunnel_dev != dev) {
+		ip_tunnel_del(itn, netdev_priv(dev));
+		unregister_netdevice_queue(dev, head);
+	}
 }
 
 int rpl_ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
@@ -642,7 +644,8 @@ void rpl_ip_tunnel_uninit(struct net_device *dev)
 	struct ip_tunnel_net *itn;
 
 	itn = net_generic(net, tunnel->ip_tnl_net_id);
-	ip_tunnel_del(itn, netdev_priv(dev));
+	if (itn->fb_tunnel_dev != dev)
+		ip_tunnel_del(itn, netdev_priv(dev));
 }
 
 /* Do least required initialization, rest of init is done in tunnel_init call */
-- 
2.7.4



More information about the dev mailing list