lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-Id: <20220810102848.282778-1-jakub@cloudflare.com> Date: Wed, 10 Aug 2022 12:28:48 +0200 From: Jakub Sitnicki <jakub@...udflare.com> To: netdev@...r.kernel.org Cc: kernel-team@...udflare.com, van fantasy <g1042620637@...il.com> Subject: [PATCH net] l2tp: Serialize access to sk_user_data with sock lock sk->sk_user_data has multiple users, which are not compatible with each other. To synchronize the users, any check-if-unused-and-set access to the pointer has to happen with sock lock held. l2tp currently fails to grab the lock when modifying the underlying tunnel socket. Fix it by adding appropriate locking. We don't to grab the lock when l2tp clears sk_user_data, because it happens only in sk->sk_destruct, when the sock is going away. Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts") Reported-by: van fantasy <g1042620637@...il.com> Tested-by: van fantasy <g1042620637@...il.com> Signed-off-by: Jakub Sitnicki <jakub@...udflare.com> --- net/l2tp/l2tp_core.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 7499c51b1850..9f5f86bfc395 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1469,16 +1469,18 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, sock = sockfd_lookup(tunnel->fd, &ret); if (!sock) goto err; - - ret = l2tp_validate_socket(sock->sk, net, tunnel->encap); - if (ret < 0) - goto err_sock; } + sk = sock->sk; + lock_sock(sk); + + ret = l2tp_validate_socket(sk, net, tunnel->encap); + if (ret < 0) + goto err_sock; + tunnel->l2tp_net = net; pn = l2tp_pernet(net); - sk = sock->sk; sock_hold(sk); tunnel->sock = sk; @@ -1504,7 +1506,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, setup_udp_tunnel_sock(net, sock, &udp_cfg); } else { - sk->sk_user_data = tunnel; + rcu_assign_sk_user_data(sk, tunnel); } tunnel->old_sk_destruct = sk->sk_destruct; @@ -1518,6 +1520,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, if (tunnel->fd >= 0) sockfd_put(sock); + release_sock(sk); return 0; err_sock: @@ -1525,6 +1528,8 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, sock_release(sock); else sockfd_put(sock); + + release_sock(sk); err: return ret; } -- 2.35.3
Powered by blists - more mailing lists