Skip to content

Commit 124da8f

Browse files
jasowangdavem330
authored andcommitted
tuntap: fix possible deadlock when fail to register netdev
Private destructor could be called when register_netdev() fail with rtnl lock held. This will lead deadlock in tun_free_netdev() who tries to hold rtnl_lock. Fixing this by switching to use spinlock to synchronize. Fixes: 96f8406 ("tun: add eBPF based queue selection method") Reported-by: Eric Dumazet <eric.dumazet@gmail.com> Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: Willem de Bruijn <willemb@google.com> Signed-off-by: Jason Wang <jasowang@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 66c5c5b commit 124da8f

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

drivers/net/tun.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2048,8 +2048,11 @@ static int __tun_set_steering_ebpf(struct tun_struct *tun,
20482048
new->prog = prog;
20492049
}
20502050

2051-
old = rtnl_dereference(tun->steering_prog);
2051+
spin_lock_bh(&tun->lock);
2052+
old = rcu_dereference_protected(tun->steering_prog,
2053+
lockdep_is_held(&tun->lock));
20522054
rcu_assign_pointer(tun->steering_prog, new);
2055+
spin_unlock_bh(&tun->lock);
20532056

20542057
if (old)
20552058
call_rcu(&old->rcu, tun_steering_prog_free);
@@ -2065,9 +2068,7 @@ static void tun_free_netdev(struct net_device *dev)
20652068
free_percpu(tun->pcpu_stats);
20662069
tun_flow_uninit(tun);
20672070
security_tun_dev_free_security(tun->security);
2068-
rtnl_lock();
20692071
__tun_set_steering_ebpf(tun, NULL);
2070-
rtnl_unlock();
20712072
}
20722073

20732074
static void tun_setup(struct net_device *dev)

0 commit comments

Comments
 (0)