aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-02-17 15:46:59 -0800
committerDavid S. Miller <davem@davemloft.net>2019-02-17 15:46:59 -0800
commite09c6a4ec1bb9ed73b4157b69c261e408d875b0f (patch)
tree26a96c9f5c6762780a5941fddcb326eb8a555449
parente928b5d6b75e239feb9c6d5488974b6646a0ebc8 (diff)
parent2c4cc9712364c051b1de2d175d5fbea6be948ebf (diff)
downloadlinux-soc-thermal-e09c6a4ec1bb9ed73b4157b69c261e408d875b0f.tar.gz
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.c2
-rw-r--r--net/ipv4/tcp_ipv4.c5
2 files changed, 5 insertions, 2 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 2079145a3b7c5f..cf3c5095c10e8e 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 efc6fef692ffdc..ec3cea9d682882 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));