diff options
author | Eric Dumazet <edumazet@google.com> | 2017-10-22 12:33:57 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-10-23 05:45:25 +0100 |
commit | a6ca7abe53633d08eea1c6756cb49c9b2d4c90bf (patch) | |
tree | 800cd8cbbd05b2d687ed7fc8d5374e318e3ba985 /net/ipv4/inet_connection_sock.c | |
parent | 3a91d29f20276fa7cd4d0c9c7f3e78b30708159d (diff) | |
download | linux-a6ca7abe53633d08eea1c6756cb49c9b2d4c90bf.tar.bz2 |
tcp/dccp: fix lockdep splat in inet_csk_route_req()
This patch fixes the following lockdep splat in inet_csk_route_req()
lockdep_rcu_suspicious
inet_csk_route_req
tcp_v4_send_synack
tcp_rtx_synack
inet_rtx_syn_ack
tcp_fastopen_synack_time
tcp_retransmit_timer
tcp_write_timer_handler
tcp_write_timer
call_timer_fn
Thread running inet_csk_route_req() owns a reference on the request
socket, so we have the guarantee ireq->ireq_opt wont be changed or
freed.
lockdep can enforce this invariant for us.
Fixes: c92e8c02fe66 ("tcp/dccp: fix ireq->opt races")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/inet_connection_sock.c')
-rw-r--r-- | net/ipv4/inet_connection_sock.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 5ec9136a7c36..18cd2eae758f 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -543,7 +543,8 @@ struct dst_entry *inet_csk_route_req(const struct sock *sk, struct ip_options_rcu *opt; struct rtable *rt; - opt = rcu_dereference(ireq->ireq_opt); + opt = rcu_dereference_protected(ireq->ireq_opt, + refcount_read(&req->rsk_refcnt) > 0); flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark, RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, sk->sk_protocol, inet_sk_flowi_flags(sk), |