diff options
author | Eric Dumazet <edumazet@google.com> | 2019-10-14 16:47:57 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-10-16 06:13:33 +0300 |
commit | cab209e571a9375f7dc6db69a6c40d2d98e57e3b (patch) | |
tree | 0a02520a515cd2b22e5fe2e0f2b178b28cb8e31f /net/ipv4 | |
parent | c9b96eb6da2a4eadf1d82d27e503ce0cd2ca43fd (diff) | |
download | linux-cab209e571a9375f7dc6db69a6c40d2d98e57e3b.tar.xz |
tcp: fix a possible lockdep splat in tcp_done()
syzbot found that if __inet_inherit_port() returns an error,
we call tcp_done() after inet_csk_prepare_forced_close(),
meaning the socket lock is no longer held.
We might fix this in a different way in net-next, but
for 5.4 it seems safer to relax the lockdep check.
Fixes: d983ea6f16b8 ("tcp: add rcu protection around tp->fastopen_rsk")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/tcp.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index b2ac4f074e2d..42187a3b82f4 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3842,8 +3842,12 @@ void tcp_done(struct sock *sk) { struct request_sock *req; - req = rcu_dereference_protected(tcp_sk(sk)->fastopen_rsk, - lockdep_sock_is_held(sk)); + /* We might be called with a new socket, after + * inet_csk_prepare_forced_close() has been called + * so we can not use lockdep_sock_is_held(sk) + */ + req = rcu_dereference_protected(tcp_sk(sk)->fastopen_rsk, 1); + if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); |