Message ID | 20190215213621.183537-2-edumazet@google.com |
---|---|
State | Accepted |
Delegated to: | David Miller |
Headers | show |
Series | tcp: fix possible crash in tcp_v4_err() | expand |
On Fri, Feb 15, 2019 at 4:36 PM Eric Dumazet <edumazet@google.com> wrote: > > soukjin bae reported a crash in tcp_v4_err() handling > ICMP_DEST_UNREACH after tcp_write_queue_head(sk) > returned a NULL pointer. > > Current logic should have prevented this : > > if (seq != tp->snd_una || !icsk->icsk_retransmits || > !icsk->icsk_backoff || fastopen) > break; > > Problem is the write queue might have been purged > and icsk_backoff has not been cleared. > > Signed-off-by: Eric Dumazet <edumazet@google.com> > Reported-by: soukjin bae <soukjin.bae@samsung.com> > --- > net/ipv4/tcp.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) Acked-by: Neal Cardwell <ncardwell@google.com> Thanks! neal
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 2079145a3b7c5f498af429c9a8289342e4421fca..cf3c5095c10e8e7e56621beae2f93c93de184489 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2528,6 +2528,7 @@ void tcp_write_queue_purge(struct sock *sk) sk_mem_reclaim(sk); tcp_clear_all_retrans_hints(tcp_sk(sk)); tcp_sk(sk)->packets_out = 0; + inet_csk(sk)->icsk_backoff = 0; } int tcp_disconnect(struct sock *sk, int flags) @@ -2576,7 +2577,6 @@ int tcp_disconnect(struct sock *sk, int flags) tp->write_seq += tp->max_window + 2; if (tp->write_seq == 0) tp->write_seq = 1; - icsk->icsk_backoff = 0; tp->snd_cwnd = 2; icsk->icsk_probes_out = 0; tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
soukjin bae reported a crash in tcp_v4_err() handling ICMP_DEST_UNREACH after tcp_write_queue_head(sk) returned a NULL pointer. Current logic should have prevented this : if (seq != tp->snd_una || !icsk->icsk_retransmits || !icsk->icsk_backoff || fastopen) break; Problem is the write queue might have been purged and icsk_backoff has not been cleared. Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: soukjin bae <soukjin.bae@samsung.com> --- net/ipv4/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)