public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	Nagaraj Arankal <nagaraj.p.arankal@hpe.com>,
	Neal Cardwell <ncardwell@google.com>,
	Yuchung Cheng <ycheng@google.com>,
	Eric Dumazet <edumazet@google.com>,
	Paolo Abeni <pabeni@redhat.com>, Sasha Levin <sashal@kernel.org>
Subject: [PATCH 4.14 55/61] tcp: fix early ETIMEDOUT after spurious non-SACK RTO
Date: Tue, 13 Sep 2022 16:07:57 +0200	[thread overview]
Message-ID: <20220913140349.208264349@linuxfoundation.org> (raw)
In-Reply-To: <20220913140346.422813036@linuxfoundation.org>

From: Neal Cardwell <ncardwell@google.com>

[ 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: da34ac7626b5 ("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>
---
 net/ipv4/tcp_input.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 906d26794d007..c6d49ec38a56a 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2425,6 +2425,21 @@ static inline bool tcp_may_undo(const struct tcp_sock *tp)
 	return tp->undo_marker && (!tp->undo_retrans || tcp_packet_delayed(tp));
 }
 
+static bool tcp_is_non_sack_preventing_reopen(struct sock *sk)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+
+	if (tp->snd_una == tp->high_seq && tcp_is_reno(tp)) {
+		/* Hold old state until something *above* high_seq
+		 * is ACKed. For Reno it is MUST to prevent false
+		 * fast retransmits (RFC2582). SACK TCP is safe. */
+		if (!tcp_any_retrans_done(sk))
+			tp->retrans_stamp = 0;
+		return true;
+	}
+	return false;
+}
+
 /* People celebrate: "We love our President!" */
 static bool tcp_try_undo_recovery(struct sock *sk)
 {
@@ -2445,14 +2460,8 @@ static bool tcp_try_undo_recovery(struct sock *sk)
 
 		NET_INC_STATS(sock_net(sk), mib_idx);
 	}
-	if (tp->snd_una == tp->high_seq && tcp_is_reno(tp)) {
-		/* Hold old state until something *above* high_seq
-		 * is ACKed. For Reno it is MUST to prevent false
-		 * fast retransmits (RFC2582). SACK TCP is safe. */
-		if (!tcp_any_retrans_done(sk))
-			tp->retrans_stamp = 0;
+	if (tcp_is_non_sack_preventing_reopen(sk))
 		return true;
-	}
 	tcp_set_ca_state(sk, TCP_CA_Open);
 	tp->is_sack_reneg = 0;
 	return false;
@@ -2486,6 +2495,8 @@ static bool tcp_try_undo_loss(struct sock *sk, bool frto_undo)
 			NET_INC_STATS(sock_net(sk),
 					LINUX_MIB_TCPSPURIOUSRTOS);
 		inet_csk(sk)->icsk_retransmits = 0;
+		if (tcp_is_non_sack_preventing_reopen(sk))
+			return true;
 		if (frto_undo || tcp_is_sack(tp)) {
 			tcp_set_ca_state(sk, TCP_CA_Open);
 			tp->is_sack_reneg = 0;
-- 
2.35.1




  parent reply	other threads:[~2022-09-13 15:27 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-13 14:07 [PATCH 4.14 00/61] 4.14.293-rc1 review Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 01/61] bpf: Verifer, adjust_scalar_min_max_vals to always call update_reg_bounds() Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 02/61] selftests/bpf: Fix test_align verifier log patterns Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 03/61] bpf: Fix the off-by-two error in range markings Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 04/61] drm/msm/dsi: Fix number of regulators for msm8996_dsi_cfg Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 05/61] platform/x86: pmc_atom: Fix SLP_TYPx bitfield mask Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 06/61] wifi: cfg80211: debugfs: fix return type in ht40allow_map_read() Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 07/61] ethernet: rocker: fix sleep in atomic context bug in neigh_timer_handler Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 08/61] kcm: fix strp_init() order and cleanup Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 09/61] serial: fsl_lpuart: RS485 RTS polariy is inverse Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 10/61] staging: rtl8712: fix use after free bugs Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 11/61] vt: Clear selection before changing the font Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 12/61] USB: serial: ftdi_sio: add Omron CS1W-CIF31 device id Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 13/61] binder: fix UAF of ref->proc caused by race condition Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 14/61] drm/i915/reg: Fix spelling mistake "Unsupport" -> "Unsupported" Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 15/61] Input: rk805-pwrkey - fix module autoloading Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 16/61] hwmon: (gpio-fan) Fix array out of bounds access Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 17/61] thunderbolt: Use the actual buffer in tb_async_error() Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 18/61] xhci: Add grace period after xHC start to prevent premature runtime suspend Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 19/61] USB: serial: cp210x: add Decagon UCA device id Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 20/61] USB: serial: option: add support for OPPO R11 diag port Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 21/61] USB: serial: option: add Quectel EM060K modem Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 22/61] USB: serial: option: add support for Cinterion MV32-WA/WB RmNet mode Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 23/61] usb: dwc2: fix wrong order of phy_power_on and phy_init Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 24/61] USB: cdc-acm: Add Icom PMR F3400 support (0c26:0020) Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 25/61] usb-storage: Add ignore-residue quirk for NXP PN7462AU Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 26/61] s390/hugetlb: fix prepare_hugepage_range() check for 2 GB hugepages Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 27/61] s390: fix nospec table alignments Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 28/61] USB: core: Prevent nested device-reset calls Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 29/61] usb: gadget: mass_storage: Fix cdrom data transfers on MAC-OS Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 30/61] wifi: mac80211: Dont finalize CSA in IBSS mode if state is disconnected Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 31/61] net: mac802154: Fix a condition in the receive path Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 32/61] ALSA: seq: oss: Fix data-race for max_midi_devs access Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 33/61] ALSA: seq: Fix data-race at module auto-loading Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 34/61] efi: capsule-loader: Fix use-after-free in efi_capsule_write Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 35/61] wifi: iwlegacy: 4965: corrected fix for potential off-by-one overflow in il4965_rs_fill_link_cmd() Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 36/61] fs: only do a memory barrier for the first set_buffer_uptodate() Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 37/61] Revert "mm: kmemleak: take a full lowmem check in kmemleak_*_phys()" Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 38/61] drm/amdgpu: Check num_gfx_rings for gfx v9_0 rb setup Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 39/61] drm/radeon: add a force flush to delay work when radeon Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 40/61] parisc: ccio-dma: Handle kmalloc failure in ccio_init_resources() Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 41/61] parisc: Add runtime check to prevent PA2.0 kernels on PA1.x machines Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 42/61] arm64/signal: Raise limit on stack frames Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 43/61] fbdev: chipsfb: Add missing pci_disable_device() in chipsfb_pci_init() Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 44/61] ALSA: emu10k1: Fix out of bounds access in snd_emu10k1_pcm_channel_alloc() Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 45/61] ALSA: aloop: Fix random zeros in capture data when using jiffies timer Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 46/61] ALSA: usb-audio: Fix an out-of-bounds bug in __snd_usb_parse_audio_interface() Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 47/61] kprobes: Prohibit probes in gate area Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 48/61] scsi: mpt3sas: Fix use-after-free warning Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 49/61] driver core: Dont probe devices after bus_type.match() probe deferral Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 50/61] netfilter: br_netfilter: Drop dst references before setting Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 51/61] netfilter: nf_conntrack_irc: Fix forged IP logic Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 52/61] sch_sfb: Dont assume the skb is still around after enqueueing to child Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 53/61] tipc: fix shift wrapping bug in map_get() Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 54/61] ipv6: sr: fix out-of-bounds read when setting HMAC data Greg Kroah-Hartman
2022-09-13 14:07 ` Greg Kroah-Hartman [this message]
2022-09-13 14:07 ` [PATCH 4.14 56/61] sch_sfb: Also store skb len before calling child enqueue Greg Kroah-Hartman
2022-09-13 14:07 ` [PATCH 4.14 57/61] usb: dwc3: fix PHY disable sequence Greg Kroah-Hartman
2022-09-13 14:08 ` [PATCH 4.14 58/61] USB: serial: ch341: fix lost character on LCR updates Greg Kroah-Hartman
2022-09-13 14:08 ` [PATCH 4.14 59/61] USB: serial: ch341: fix disabled rx timer on older devices Greg Kroah-Hartman
2022-09-13 14:08 ` [PATCH 4.14 60/61] MIPS: loongson32: ls1c: Fix hang during startup Greg Kroah-Hartman
2022-09-13 14:08 ` [PATCH 4.14 61/61] SUNRPC: use _bh spinlocking on ->transport_lock Greg Kroah-Hartman
2022-09-14 12:37 ` [PATCH 4.14 00/61] 4.14.293-rc1 review Naresh Kamboju
2022-09-15  0:15 ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220913140349.208264349@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=edumazet@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nagaraj.p.arankal@hpe.com \
    --cc=ncardwell@google.com \
    --cc=pabeni@redhat.com \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=ycheng@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox