diff options
author | Eric Dumazet <edumazet@google.com> | 2016-10-20 09:39:40 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-10-20 14:45:52 -0400 |
commit | 286c72deabaa240b7eebbd99496ed3324d69f3c0 (patch) | |
tree | 00a0b07bfc20b08a025720c4c1b3c724ed4eaf67 /net/l2tp/l2tp_ip.c | |
parent | 2399d6143f85b155ae84ccd94237befd36b8f6c7 (diff) | |
download | linux-286c72deabaa240b7eebbd99496ed3324d69f3c0.tar.gz |
udp: must lock the socket in udp_disconnect()
Baozeng Ding reported KASAN traces showing uses after free in udp_lib_get_port() and other related UDP functions. A CONFIG_DEBUG_PAGEALLOC=y kernel would eventually crash. I could write a reproducer with two threads doing : static int sock_fd; static void *thr1(void *arg) { for (;;) { connect(sock_fd, (const struct sockaddr *)arg, sizeof(struct sockaddr_in)); } } static void *thr2(void *arg) { struct sockaddr_in unspec; for (;;) { memset(&unspec, 0, sizeof(unspec)); connect(sock_fd, (const struct sockaddr *)&unspec, sizeof(unspec)); } } Problem is that udp_disconnect() could run without holding socket lock, and this was causing list corruptions. Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: Baozeng Ding <sploving1@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/l2tp/l2tp_ip.c')
-rw-r--r-- | net/l2tp/l2tp_ip.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 42de4ccd159f..fce25afb652a 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -338,7 +338,7 @@ static int l2tp_ip_disconnect(struct sock *sk, int flags) if (sock_flag(sk, SOCK_ZAPPED)) return 0; - return udp_disconnect(sk, flags); + return __udp_disconnect(sk, flags); } static int l2tp_ip_getname(struct socket *sock, struct sockaddr *uaddr, |