diff options
author | Vladislav Efanov <VEfanov@ispras.ru> | 2023-05-30 14:39:41 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2023-05-31 10:35:10 +0100 |
commit | 448a5ce1120c5bdbce1f1ccdabcd31c7d029f328 (patch) | |
tree | 964d1aa81d1b7208bebd2de62bb273cb22770340 /net | |
parent | f4e4534850a9d18c250a93f8d7fbb51310828110 (diff) | |
download | linux-stable-448a5ce1120c5bdbce1f1ccdabcd31c7d029f328.tar.gz linux-stable-448a5ce1120c5bdbce1f1ccdabcd31c7d029f328.tar.bz2 linux-stable-448a5ce1120c5bdbce1f1ccdabcd31c7d029f328.zip |
udp6: Fix race condition in udp6_sendmsg & connect
Syzkaller got the following report:
BUG: KASAN: use-after-free in sk_setup_caps+0x621/0x690 net/core/sock.c:2018
Read of size 8 at addr ffff888027f82780 by task syz-executor276/3255
The function sk_setup_caps (called by ip6_sk_dst_store_flow->
ip6_dst_store) referenced already freed memory as this memory was
freed by parallel task in udpv6_sendmsg->ip6_sk_dst_lookup_flow->
sk_dst_check.
task1 (connect) task2 (udp6_sendmsg)
sk_setup_caps->sk_dst_set |
| sk_dst_check->
| sk_dst_set
| dst_release
sk_setup_caps references |
to already freed dst_entry|
The reason for this race condition is: sk_setup_caps() keeps using
the dst after transferring the ownership to the dst cache.
Found by Linux Verification Center (linuxtesting.org) with syzkaller.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Vladislav Efanov <VEfanov@ispras.ru>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/sock.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index 5440e67bcfe3..24f2761bdb1d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2381,7 +2381,6 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst) { u32 max_segs = 1; - sk_dst_set(sk, dst); sk->sk_route_caps = dst->dev->features; if (sk_is_tcp(sk)) sk->sk_route_caps |= NETIF_F_GSO; @@ -2400,6 +2399,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst) } } sk->sk_gso_max_segs = max_segs; + sk_dst_set(sk, dst); } EXPORT_SYMBOL_GPL(sk_setup_caps); |