Skip to content

Commit 1df0d87

Browse files
TaeheeYoointel-lab-lkp
authored andcommitted
ip_tunnel: fix use-after-free in ip_tunnel_lookup()
In the datapath, the ip_tunnel_lookup() is used and it internally uses fallback tunnel device pointer, which is fb_tunnel_dev. This pointer variable should be set to NULL when a fb interface is deleted. But there is no routine to set fb_tunnel_dev pointer to NULL. So, this pointer will be still used after interface is deleted and it eventually results in the use-after-free problem. Test commands: ip netns add A ip netns add B ip link add eth0 type veth peer name eth1 ip link set eth0 netns A ip link set eth1 netns B ip netns exec A ip link set lo up ip netns exec A ip link set eth0 up ip netns exec A ip link add gre1 type gre local 10.0.0.1 \ remote 10.0.0.2 ip netns exec A ip link set gre1 up ip netns exec A ip a a 10.0.100.1/24 dev gre1 ip netns exec A ip a a 10.0.0.1/24 dev eth0 ip netns exec B ip link set lo up ip netns exec B ip link set eth1 up ip netns exec B ip link add gre1 type gre local 10.0.0.2 \ remote 10.0.0.1 ip netns exec B ip link set gre1 up ip netns exec B ip a a 10.0.100.2/24 dev gre1 ip netns exec B ip a a 10.0.0.2/24 dev eth1 ip netns exec A hping3 10.0.100.2 -2 --flood -d 60000 & ip netns del B Splat looks like: [ 133.319668][ C3] BUG: KASAN: use-after-free in ip_tunnel_lookup+0x9d6/0xde0 [ 133.343852][ C3] Read of size 4 at addr ffff8880b1701c84 by task hping3/1222 [ 133.344724][ C3] [ 133.345002][ C3] CPU: 3 PID: 1222 Comm: hping3 Not tainted 5.7.0+ torvalds#591 [ 133.345814][ C3] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 133.373336][ C3] Call Trace: [ 133.374792][ C3] <IRQ> [ 133.375205][ C3] dump_stack+0x96/0xdb [ 133.375789][ C3] print_address_description.constprop.6+0x2cc/0x450 [ 133.376720][ C3] ? ip_tunnel_lookup+0x9d6/0xde0 [ 133.377431][ C3] ? ip_tunnel_lookup+0x9d6/0xde0 [ 133.378130][ C3] ? ip_tunnel_lookup+0x9d6/0xde0 [ 133.378851][ C3] kasan_report+0x154/0x190 [ 133.379494][ C3] ? ip_tunnel_lookup+0x9d6/0xde0 [ 133.380200][ C3] ip_tunnel_lookup+0x9d6/0xde0 [ 133.380894][ C3] __ipgre_rcv+0x1ab/0xaa0 [ip_gre] [ 133.381630][ C3] ? rcu_read_lock_sched_held+0xc0/0xc0 [ 133.382429][ C3] gre_rcv+0x304/0x1910 [ip_gre] [ ... ] Suggested-by: Eric Dumazet <eric.dumazet@gmail.com> Fixes: c544193 ("GRE: Refactor GRE tunneling code.") Signed-off-by: Taehee Yoo <ap420073@gmail.com>
1 parent b8ad540 commit 1df0d87

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

net/ipv4/ip_tunnel.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,10 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
8585
__be32 remote, __be32 local,
8686
__be32 key)
8787
{
88-
unsigned int hash;
8988
struct ip_tunnel *t, *cand = NULL;
9089
struct hlist_head *head;
90+
struct net_device *ndev;
91+
unsigned int hash;
9192

9293
hash = ip_tunnel_hash(key, remote);
9394
head = &itn->tunnels[hash];
@@ -162,8 +163,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
162163
if (t && t->dev->flags & IFF_UP)
163164
return t;
164165

165-
if (itn->fb_tunnel_dev && itn->fb_tunnel_dev->flags & IFF_UP)
166-
return netdev_priv(itn->fb_tunnel_dev);
166+
ndev = READ_ONCE(itn->fb_tunnel_dev);
167+
if (ndev && ndev->flags & IFF_UP)
168+
return netdev_priv(ndev);
167169

168170
return NULL;
169171
}
@@ -1260,8 +1262,9 @@ void ip_tunnel_uninit(struct net_device *dev)
12601262

12611263
itn = net_generic(net, tunnel->ip_tnl_net_id);
12621264
/* fb_tunnel_dev will be unregisted in net-exit call. */
1263-
if (itn->fb_tunnel_dev != dev)
1264-
ip_tunnel_del(itn, netdev_priv(dev));
1265+
ip_tunnel_del(itn, netdev_priv(dev));
1266+
if (itn->fb_tunnel_dev == dev)
1267+
WRITE_ONCE(itn->fb_tunnel_dev, NULL);
12651268

12661269
dst_cache_reset(&tunnel->dst_cache);
12671270
}

0 commit comments

Comments
 (0)