| 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 |
| |