Skip to content

Commit 77e8ed7

Browse files
Cong Wanggregkh
authored andcommitted
l2tp: close all race conditions in l2tp_tunnel_register()
[ Upstream commit 0b2c597 ] The code in l2tp_tunnel_register() is racy in several ways: 1. It modifies the tunnel socket _after_ publishing it. 2. It calls setup_udp_tunnel_sock() on an existing socket without locking. 3. It changes sock lock class on fly, which triggers many syzbot reports. This patch amends all of them by moving socket initialization code before publishing and under sock lock. As suggested by Jakub, the l2tp lockdep class is not necessary as we can just switch to bh_lock_sock_nested(). Fixes: 37159ef ("l2tp: fix a lockdep splat") Fixes: 6b9f342 ("l2tp: fix races in tunnel creation") Reported-by: [email protected] Reported-by: [email protected] Reported-by: Tetsuo Handa <[email protected]> Cc: Guillaume Nault <[email protected]> Cc: Jakub Sitnicki <[email protected]> Cc: Eric Dumazet <[email protected]> Cc: Tom Parkin <[email protected]> Signed-off-by: Cong Wang <[email protected]> Reviewed-by: Guillaume Nault <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent af22d2c commit 77e8ed7

File tree

1 file changed

+14
-14
lines changed

1 file changed

+14
-14
lines changed

net/l2tp/l2tp_core.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns
10411041
IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED);
10421042
nf_reset_ct(skb);
10431043

1044-
bh_lock_sock(sk);
1044+
bh_lock_sock_nested(sk);
10451045
if (sock_owned_by_user(sk)) {
10461046
kfree_skb(skb);
10471047
ret = NET_XMIT_DROP;
@@ -1387,8 +1387,6 @@ static int l2tp_tunnel_sock_create(struct net *net,
13871387
return err;
13881388
}
13891389

1390-
static struct lock_class_key l2tp_socket_class;
1391-
13921390
int l2tp_tunnel_create(int fd, int version, u32 tunnel_id, u32 peer_tunnel_id,
13931391
struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp)
13941392
{
@@ -1484,21 +1482,16 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
14841482
}
14851483

14861484
sk = sock->sk;
1485+
lock_sock(sk);
14871486
write_lock_bh(&sk->sk_callback_lock);
14881487
ret = l2tp_validate_socket(sk, net, tunnel->encap);
1489-
if (ret < 0)
1488+
if (ret < 0) {
1489+
release_sock(sk);
14901490
goto err_inval_sock;
1491+
}
14911492
rcu_assign_sk_user_data(sk, tunnel);
14921493
write_unlock_bh(&sk->sk_callback_lock);
14931494

1494-
sock_hold(sk);
1495-
tunnel->sock = sk;
1496-
tunnel->l2tp_net = net;
1497-
1498-
spin_lock_bh(&pn->l2tp_tunnel_idr_lock);
1499-
idr_replace(&pn->l2tp_tunnel_idr, tunnel, tunnel->tunnel_id);
1500-
spin_unlock_bh(&pn->l2tp_tunnel_idr_lock);
1501-
15021495
if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
15031496
struct udp_tunnel_sock_cfg udp_cfg = {
15041497
.sk_user_data = tunnel,
@@ -1512,9 +1505,16 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
15121505

15131506
tunnel->old_sk_destruct = sk->sk_destruct;
15141507
sk->sk_destruct = &l2tp_tunnel_destruct;
1515-
lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class,
1516-
"l2tp_sock");
15171508
sk->sk_allocation = GFP_ATOMIC;
1509+
release_sock(sk);
1510+
1511+
sock_hold(sk);
1512+
tunnel->sock = sk;
1513+
tunnel->l2tp_net = net;
1514+
1515+
spin_lock_bh(&pn->l2tp_tunnel_idr_lock);
1516+
idr_replace(&pn->l2tp_tunnel_idr, tunnel, tunnel->tunnel_id);
1517+
spin_unlock_bh(&pn->l2tp_tunnel_idr_lock);
15181518

15191519
trace_register_tunnel(tunnel);
15201520

0 commit comments

Comments
 (0)