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>
This commit is contained in:

committed by
David S. Miller

parent
2399d6143f
commit
286c72deab
@@ -258,6 +258,7 @@ void udp_flush_pending_frames(struct sock *sk);
|
||||
void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst);
|
||||
int udp_rcv(struct sk_buff *skb);
|
||||
int udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
|
||||
int __udp_disconnect(struct sock *sk, int flags);
|
||||
int udp_disconnect(struct sock *sk, int flags);
|
||||
unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait);
|
||||
struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
|
||||
|
Reference in New Issue
Block a user