diff options
| author | Eric Dumazet <edumazet@google.com> | 2026-02-17 19:12:05 +0300 |
|---|---|---|
| committer | Sasha Levin <sashal@kernel.org> | 2026-03-04 15:20:44 +0300 |
| commit | fe89b2f05b854847784f91127319172945c1fadd (patch) | |
| tree | 8951b195189127a650ec7934149fbbe12c6636d5 /include | |
| parent | 82c5acb68c6390b9b5c402cac484406ad9c3ba28 (diff) | |
| download | linux-fe89b2f05b854847784f91127319172945c1fadd.tar.xz | |
tcp: fix potential race in tcp_v6_syn_recv_sock()
[ Upstream commit 858d2a4f67ff69e645a43487ef7ea7f28f06deae ]
Code in tcp_v6_syn_recv_sock() after the call to tcp_v4_syn_recv_sock()
is done too late.
After tcp_v4_syn_recv_sock(), the child socket is already visible
from TCP ehash table and other cpus might use it.
Since newinet->pinet6 is still pointing to the listener ipv6_pinfo
bad things can happen as syzbot found.
Move the problematic code in tcp_v6_mapped_child_init()
and call this new helper from tcp_v4_syn_recv_sock() before
the ehash insertion.
This allows the removal of one tcp_sync_mss(), since
tcp_v4_syn_recv_sock() will call it with the correct
context.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: syzbot+937b5bbb6a815b3e5d0b@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/69949275.050a0220.2eeac1.0145.GAE@google.com/
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260217161205.2079883-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/net/inet_connection_sock.h | 4 | ||||
| -rw-r--r-- | include/net/tcp.h | 4 |
2 files changed, 6 insertions, 2 deletions
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index b4b886647607..afec146b8baf 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -42,7 +42,9 @@ struct inet_connection_sock_af_ops { struct request_sock *req, struct dst_entry *dst, struct request_sock *req_unhash, - bool *own_req); + bool *own_req, + void (*opt_child_init)(struct sock *newsk, + const struct sock *sk)); u16 net_header_len; int (*setsockopt)(struct sock *sk, int level, int optname, sockptr_t optval, unsigned int optlen); diff --git a/include/net/tcp.h b/include/net/tcp.h index 3c84d95cdba8..aa4d24c42a27 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -528,7 +528,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, struct request_sock *req, struct dst_entry *dst, struct request_sock *req_unhash, - bool *own_req); + bool *own_req, + void (*opt_child_init)(struct sock *newsk, + const struct sock *sk)); int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb); int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); int tcp_connect(struct sock *sk); |
