Hi there,

we find a special case for Linux TCP undo operations where
tp->snd_cwnd could be extremely large (e.g., 4294967294) by two
consecutive cwnd undo operations when using
reno/veno/vegas/highspeed/HTCP/yeah/westwood/hybla/illinois/scalable/lp
congestion control algorithms in the latest long-term kernel 4.9.

e.g., a simple trace for sender-side tcp state variables
cwnd               ssthresh              ca_state
10                   2147483647            0
10                   2147483647            0
1                           5                        4
11                    2147483647           4                   first
undo operation
4294967294    2147483647           0                   second undo operation
4294967294    2147483647           0


By debugging the code, we find that the second undo operation was
triggered by F-RTO mechanism without checking current tp->undo_marker.

The case should be existing for all kernel versions depending on F-RTO
internals (i.e., this bug exists for kernels 4.10 and earlier)

Just Let you know in case of some vulnerabilities as it is not hard to
trigger this specific case.

Attached is a simple Google's packetdrill script to trigger it and a
possible patch to fix it. Thanks
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 7727ffe..da23221 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2733,7 +2733,7 @@ static void tcp_process_loss(struct sock *sk, int flag, 
bool is_dupack,
                 * lost, i.e., never-retransmitted data are (s)acked.
                 */
                if ((flag & FLAG_ORIG_SACK_ACKED) &&
-                   tcp_try_undo_loss(sk, true))
+                   tcp_try_undo_loss(sk, tp->undo_marker))
                        return;
 
                if (after(tp->snd_nxt, tp->high_seq)) {

Attachment: reproduce.pkt
Description: Binary data

Reply via email to