diff options
author | David S. Miller <davem@davemloft.net> | 2019-02-17 15:46:59 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-02-17 15:46:59 -0800 |
commit | e09c6a4ec1bb9ed73b4157b69c261e408d875b0f (patch) | |
tree | 26a96c9f5c6762780a5941fddcb326eb8a555449 | |
parent | e928b5d6b75e239feb9c6d5488974b6646a0ebc8 (diff) | |
parent | 2c4cc9712364c051b1de2d175d5fbea6be948ebf (diff) | |
download | linux-e09c6a4ec1bb9ed73b4157b69c261e408d875b0f.tar.gz linux-e09c6a4ec1bb9ed73b4157b69c261e408d875b0f.tar.bz2 linux-e09c6a4ec1bb9ed73b4157b69c261e408d875b0f.zip |
Merge branch 'tcp-fix-possible-crash-in-tcp_v4_err'
Eric Dumazet says:
====================
tcp: fix possible crash in tcp_v4_err()
soukjin bae reported a crash in tcp_v4_err() that we
root caused to a missing initialization.
Second patch adds a sanity check in tcp_v4_err() to avoid
future potential problems. Ignoring an ICMP message
is probably better than crashing a machine.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/tcp.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 5 |
2 files changed, 5 insertions, 2 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 2079145a3b7c..cf3c5095c10e 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; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index efc6fef692ff..ec3cea9d6828 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -536,12 +536,15 @@ int tcp_v4_err(struct sk_buff *icmp_skb, u32 info) if (sock_owned_by_user(sk)) break; + skb = tcp_rtx_queue_head(sk); + if (WARN_ON_ONCE(!skb)) + break; + icsk->icsk_backoff--; icsk->icsk_rto = tp->srtt_us ? __tcp_set_rto(tp) : TCP_TIMEOUT_INIT; icsk->icsk_rto = inet_csk_rto_backoff(icsk, TCP_RTO_MAX); - skb = tcp_rtx_queue_head(sk); tcp_mstamp_refresh(tp); delta_us = (u32)(tp->tcp_mstamp - tcp_skb_timestamp_us(skb)); |