diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 7499c51b1850..07429bed7c4c 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1382,8 +1382,6 @@ static int l2tp_tunnel_sock_create(struct net *net, return err; } -static struct lock_class_key l2tp_socket_class; - int l2tp_tunnel_create(int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp) { @@ -1509,8 +1507,20 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, tunnel->old_sk_destruct = sk->sk_destruct; sk->sk_destruct = &l2tp_tunnel_destruct; - lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, - "l2tp_sock"); + if (IS_ENABLED(CONFIG_LOCKDEP)) { + static struct lock_class_key l2tp_socket_class; + + /* Changing class/name of an already visible sock might race + * with first lock_sock() call on that sock. In order to make + * sure that register_lock_class() has completed before + * lockdep_set_class_and_name() changes class/name, explicitly + * lock/release that sock. + */ + lock_sock(sk); + release_sock(sk); + lockdep_set_class_and_name(&sk->sk_lock.slock, + &l2tp_socket_class, "l2tp_sock"); + } sk->sk_allocation = GFP_ATOMIC; trace_register_tunnel(tunnel);