blob: e4cf6079ed13f0d466329f4231d03d2229db49df [file] [log] [blame]
From 57115451c7e5428b752b689b3af32c84fdc1ae34 Mon Sep 17 00:00:00 2001
From: Eric Dumazet <edumazet@google.com>
Date: Mon, 14 Oct 2019 06:47:57 -0700
Subject: [PATCH] tcp: fix a possible lockdep splat in tcp_done()
commit cab209e571a9375f7dc6db69a6c40d2d98e57e3b upstream.
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>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index cea071def651..de6c051e8f6d 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3809,8 +3809,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);
--
2.7.4