android_kernel_xiaomi_sm8350/net/ipv4
Neal Cardwell 9d3237b590 tcp: fix early ETIMEDOUT after spurious non-SACK RTO
[ Upstream commit 686dc2db2a0fdc1d34b424ec2c0a735becd8d62b ]

Fix a bug reported and analyzed by Nagaraj Arankal, where the handling
of a spurious non-SACK RTO could cause a connection to fail to clear
retrans_stamp, causing a later RTO to very prematurely time out the
connection with ETIMEDOUT.

Here is the buggy scenario, expanding upon Nagaraj Arankal's excellent
report:

(*1) Send one data packet on a non-SACK connection

(*2) Because no ACK packet is received, the packet is retransmitted
     and we enter CA_Loss; but this retransmission is spurious.

(*3) The ACK for the original data is received. The transmitted packet
     is acknowledged.  The TCP timestamp is before the retrans_stamp,
     so tcp_may_undo() returns true, and tcp_try_undo_loss() returns
     true without changing state to Open (because tcp_is_sack() is
     false), and tcp_process_loss() returns without calling
     tcp_try_undo_recovery().  Normally after undoing a CA_Loss
     episode, tcp_fastretrans_alert() would see that the connection
     has returned to CA_Open and fall through and call
     tcp_try_to_open(), which would set retrans_stamp to 0.  However,
     for non-SACK connections we hold the connection in CA_Loss, so do
     not fall through to call tcp_try_to_open() and do not set
     retrans_stamp to 0. So retrans_stamp is (erroneously) still
     non-zero.

     At this point the first "retransmission event" has passed and
     been recovered from. Any future retransmission is a completely
     new "event". However, retrans_stamp is erroneously still
     set. (And we are still in CA_Loss, which is correct.)

(*4) After 16 minutes (to correspond with tcp_retries2=15), a new data
     packet is sent. Note: No data is transmitted between (*3) and
     (*4) and we disabled keep alives.

     The socket's timeout SHOULD be calculated from this point in
     time, but instead it's calculated from the prior "event" 16
     minutes ago (step (*2)).

(*5) Because no ACK packet is received, the packet is retransmitted.

(*6) At the time of the 2nd retransmission, the socket returns
     ETIMEDOUT, prematurely, because retrans_stamp is (erroneously)
     too far in the past (set at the time of (*2)).

This commit fixes this bug by ensuring that we reuse in
tcp_try_undo_loss() the same careful logic for non-SACK connections
that we have in tcp_try_undo_recovery(). To avoid duplicating logic,
we factor out that logic into a new
tcp_is_non_sack_preventing_reopen() helper and call that helper from
both undo functions.

Fixes: da34ac7626 ("tcp: only undo on partial ACKs in CA_Loss")
Reported-by: Nagaraj Arankal <nagaraj.p.arankal@hpe.com>
Link: https://lore.kernel.org/all/SJ0PR84MB1847BE6C24D274C46A1B9B0EB27A9@SJ0PR84MB1847.NAMPRD84.PROD.OUTLOOK.COM/
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20220903121023.866900-1-ncardwell.kernel@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2022-09-15 12:04:56 +02:00
..
bpfilter
netfilter netfilter: ipt_CLUSTERIP: fix refcount leak in clusterip_tg_check() 2022-01-27 09:19:35 +01:00
af_inet.c tcp: Fix data-races around sysctl_tcp_fastopen. 2022-07-29 17:14:13 +02:00
ah4.c
arp.c ipv4: Invalidate neighbour for broadcast address upon address addition 2022-04-15 14:18:33 +02:00
cipso_ipv4.c cipso: Fix data-races around sysctl. 2022-07-21 20:59:20 +02:00
datagram.c
devinet.c net: return correct error code 2021-12-08 09:01:09 +01:00
esp4_offload.c esp: delete NETIF_F_SCTP_CRC bit from features for esp offload 2021-04-14 08:24:13 +02:00
esp4.c esp: limit skb_page_frag_refill use to a single page 2022-07-12 16:30:45 +02:00
fib_frontend.c ip: fix triggering of 'icmp redirect' 2022-09-15 12:04:53 +02:00
fib_lookup.h
fib_notifier.c
fib_rules.c ipv6: fix memory leak in fib6_rule_suppress 2021-12-08 09:01:13 +01:00
fib_semantics.c ipv4: Fix a data-race around sysctl_fib_multipath_use_neigh. 2022-07-29 17:14:14 +02:00
fib_trie.c ipv4: Fix a data-race around sysctl_fib_sync_mem. 2022-07-21 20:59:21 +02:00
fou.c
gre_demux.c erspan: fix version 1 check in gre_parse_header() 2021-01-12 20:16:15 +01:00
gre_offload.c net: gre: recompute gre csum for sctp over gre tunnels 2020-08-11 15:33:40 +02:00
icmp.c ip: Fix data-races around sysctl_ip_no_pmtu_disc. 2022-07-29 17:14:10 +02:00
igmp.c igmp: Fix data-races around sysctl_igmp_qrv. 2022-08-03 11:59:39 +02:00
inet_connection_sock.c tcp: fix race condition when creating child sockets from syncookies 2022-04-27 13:50:45 +02:00
inet_diag.c inet_diag: fix kernel-infoleak for UDP sockets 2021-12-22 09:29:36 +01:00
inet_fragment.c inet: frags: annotate races around fqdir->dead and fqdir->high_thresh 2022-01-27 09:19:54 +01:00
inet_hashtables.c tcp: drop the hash_32() part from the index calculation 2022-06-25 12:44:36 +02:00
inet_timewait_sock.c
inetpeer.c inetpeer: Fix data-races around sysctl. 2022-07-21 20:59:20 +02:00
ip_forward.c
ip_fragment.c inet: frags: annotate races around fqdir->dead and fqdir->high_thresh 2022-01-27 09:19:54 +01:00
ip_gre.c erspan: do not assume transport header is always set 2022-06-29 08:58:46 +02:00
ip_input.c
ip_options.c
ip_output.c ipv4: tcp: send zero IPID in SYNACK messages 2022-02-01 17:24:39 +01:00
ip_sockglue.c
ip_tunnel_core.c
ip_tunnel.c net: Set true network header for ECN decapsulation 2021-08-04 12:27:39 +02:00
ip_vti.c
ipcomp.c
ipconfig.c net: ipconfig: Don't override command-line hostnames or domains 2021-06-18 09:58:59 +02:00
ipip.c
ipmr_base.c
ipmr.c ipmr,ip6mr: acquire RTNL before calling ip[6]mr_free_table() on failure path 2022-02-16 12:52:51 +01:00
Kconfig
Makefile
metrics.c
netfilter.c netfilter: use actual socket sk rather than skb sk when routing harder 2020-11-18 19:20:17 +01:00
netlink.c
nexthop.c net: nexthop: release IPv6 per-cpu dsts when replacing a nexthop group 2021-12-01 09:23:33 +01:00
ping.c ping: fix address binding wrt vrf 2022-05-18 09:47:28 +02:00
proc.c
protocol.c
raw_diag.c
raw.c ipv4: raw: lock the socket in raw_bind() 2022-02-01 17:24:39 +01:00
route.c ip: Fix data-races around sysctl_ip_fwd_use_pmtu. 2022-07-29 17:14:10 +02:00
syncookies.c tcp: Fix data-races around sysctl knobs related to SYN option. 2022-07-29 17:14:14 +02:00
sysctl_net_ipv4.c tcp: correct read of TFO keys on big endian systems 2020-08-19 08:16:23 +02:00
tcp_bbr.c tcp_bbr: fix u32 wrap bug in round logic if bbr_init() called after 2B packets 2021-08-18 08:57:01 +02:00
tcp_bic.c
tcp_bpf.c bpf, sockmap: Fix double uncharge the mem of sk_msg 2022-04-15 14:18:16 +02:00
tcp_cdg.c
tcp_cong.c net: Only allow init netns to set default tcp cong to a restricted algo 2021-05-14 09:44:33 +02:00
tcp_cubic.c tcp_cubic: fix spurious Hystart ACK train detections for not-cwnd-limited flows 2021-12-01 09:23:33 +01:00
tcp_dctcp.c
tcp_dctcp.h
tcp_diag.c
tcp_fastopen.c tcp: Fix data-races around sysctl_tcp_fastopen. 2022-07-29 17:14:13 +02:00
tcp_highspeed.c
tcp_htcp.c
tcp_hybla.c
tcp_illinois.c
tcp_input.c tcp: fix early ETIMEDOUT after spurious non-SACK RTO 2022-09-15 12:04:56 +02:00
tcp_ipv4.c tcp: Fix a data-race around sysctl_tcp_tw_reuse. 2022-07-29 17:14:13 +02:00
tcp_lp.c
tcp_metrics.c tcp: Fix a data-race around sysctl_tcp_nometrics_save. 2022-08-03 11:59:38 +02:00
tcp_minisocks.c tcp: Fix a data-race around sysctl_tcp_rfc1337. 2022-07-29 17:14:15 +02:00
tcp_nv.c
tcp_offload.c net, gro: Set inner transport header offset in tcp/udp GRO hook 2021-08-12 13:20:56 +02:00
tcp_output.c tcp: fix over estimation in sk_forced_mem_schedule() 2022-08-25 11:18:17 +02:00
tcp_rate.c tcp: ensure to use the most recently sent skb when filling the rate sample 2022-05-09 09:03:24 +02:00
tcp_recovery.c tcp: Fix data-races around sysctl_tcp_recovery. 2022-07-29 17:14:15 +02:00
tcp_scalable.c
tcp_timer.c tcp: Fix a data-race around sysctl_tcp_thin_linear_timeouts. 2022-07-29 17:14:15 +02:00
tcp_ulp.c
tcp_vegas.c
tcp_vegas.h
tcp_veno.c
tcp_westwood.c
tcp_yeah.c
tcp.c tcp: Fix a data-race around sysctl_tcp_autocorking. 2022-08-03 11:59:39 +02:00
tunnel4.c
udp_diag.c
udp_impl.h
udp_offload.c net, gro: Set inner transport header offset in tcp/udp GRO hook 2021-08-12 13:20:56 +02:00
udp_tunnel.c
udp.c udp: call udp_encap_enable for v6 sockets when enabling encap 2022-04-15 14:18:01 +02:00
udplite.c
xfrm4_input.c
xfrm4_output.c
xfrm4_policy.c
xfrm4_protocol.c net: xfrm: unexport __init-annotated xfrm4_protocol_init() 2022-06-14 18:11:58 +02:00
xfrm4_state.c
xfrm4_tunnel.c