Page MenuHomeFreeBSD

Address rescue retransmission and FIN overlap
ClosedPublic

Authored by rscheff on Mar 17 2021, 3:23 PM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Dec 24, 5:07 AM
Unknown Object (File)
Sat, Dec 14, 3:20 AM
Unknown Object (File)
Wed, Dec 4, 10:27 AM
Unknown Object (File)
Tue, Dec 3, 11:57 PM
Unknown Object (File)
Nov 20 2024, 7:23 PM
Unknown Object (File)
Oct 30 2024, 6:53 AM
Unknown Object (File)
Oct 10 2024, 2:30 AM
Unknown Object (File)
Sep 29 2024, 9:58 PM
Subscribers

Details

Summary

The FIN bit is using Sequence Number Space.
Thus a rescue retransmission at the tail end
of a session which is being closed could be
off-by-one, and lead to a invalid memory free.

Also, if the partial ACK only Acks the data,
but not the FIN bit, that could also lead to
the creation of a SACK hole with start==end.

PR254309
PR254244

Test Plan

packetdrill script to recreate the issue and
also validate the proper operation:
'''

A simple test to verify behavior when SACK retransmission is lost

--tolerance_usecs=200000

0.0 sysctl net.inet.tcp.cc.algorithm=newreno
+0.0 sysctl net.inet.tcp.initcwnd_segments=10
+0.0 sysctl net.inet.tcp.rexmit_slop=1000
+0.0 sysctl net.inet.tcp.do_prr=0
+0.0 sysctl net.inet.tcp.do_prr_conservative=0
+0.0 sysctl net.inet.tcp.rfc6675_pipe=1
+0.0 sysctl net.inet.tcp.hostcache.purgenow=1

// Create a listening TCP socket.

+0.50 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0.01 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0.01 setsockopt(3, SOL_SOCKET, SO_SNDBUF, [1048576], 4) = 0
+0.01 setsockopt(3, SOL_SOCKET, SO_DEBUG, [1], 4) = 0
+0.01 bind(3, ..., ...) = 0
+0.01 listen(3, 1) = 0

// Establish a TCP connection.
+0.05 < S 0:0(0) win 65535 <mss 1000, sackOK, wscale 9, nop, nop, nop >
+0.00 > S. 0:0(0) ack 1 win 65535 <...>
+0.00 < . 1:1(0) ack 1 win 65535
+0.00 accept(3, ..., ...) = 4

Write some data to be sent to the simulated packetdrill receiver.
// Note: More than 33kB appears to get stuck on BSD
+0.20 write(4, ..., 20000) = 20000
+0.00 close(4) = 0

+0.00 > . 1:1001(1000) ack 1
+0.00 > . 1001:2001(1000) ack 1
+0.00 > . 2001:3001(1000) ack 1
+0.00 > . 3001:4001(1000) ack 1
+0.00 > . 4001:5001(1000) ack 1
+0.00 > . 5001:6001(1000) ack 1
+0.00 > . 6001:7001(1000) ack 1
+0.00 > . 7001:8001(1000) ack 1
+0.00 > . 8001:9001(1000) ack 1
+0.00 > . 9001:10001(1000) ack 1
+0.01 < . 1:1(0) ack 1001 win 65535 ACKing every packet
+0.00 > . 10001:11001(1000) ack 1
+0.00 > . 11001:12001(1000) ack 1
+0.01 < . 1:1(0) ack 2001 win 65535
to built up cwnd fast
+0.00 > . 12001:13001(1000) ack 1
+0.00 > . 13001:14001(1000) ack 1
+0.01 < . 1:1(0) ack 3001 win 65535
+0.00 > . 14001:15001(1000) ack 1
+0.00 > . 15001:16001(1000) ack 1
+0.01 < . 1:1(0) ack 4001 win 65535
+0.00 > . 16001:17001(1000) ack 1
+0.00 > . 17001:18001(1000) ack 1
+0.01 < . 1:1(0) ack 5001 win 65535
+0.00 > . 18001:19001(1000) ack 1
+0.00 > FP. 19001:20001(1000) ack 1
+0.01 < . 1:1(0) ack 6001 win 65535
+0.01 < . 1:1(0) ack 7001 win 65535
+0.01 < . 1:1(0) ack 8001 win 65535
+0.01 < . 1:1(0) ack 9001 win 65535
+0.01 < . 1:1(0) ack 10001 win 65535
+0.01 < . 1:1(0) ack 10001 win 65535 <sack 11001:12001,nop,nop>
+0.01 < . 1:1(0) ack 10001 win 65535 <sack 11001:13001,nop,nop>
+0.01 < . 1:1(0) ack 10001 win 65535 <sack 11001:14001,nop,nop>
+0.00 > . 10001:11001(1000) ack 1
+0.01 < . 1:1(0) ack 14001 win 65535
+0.00 > FP. 19001:20001(1000) ack 1 // Rescue Retransmission with FIN
+0.01 < . 1:1(0) ack 14001 win 65535 <sack 19001:20001,nop,nop>
+0.00 > . 14001:15001(1000) ack 1
+0.00 > . 15001:16001(1000) ack 1
+0.01 < . 1:1(0) ack 15001 win 65535 <sack 19001:20001,nop,nop>
+0.00 > . 16001:17001(1000) ack 1
+0.01 < . 1:1(0) ack 16001 win 65535 <sack 19001:20001,nop,nop>
+0.00 > . 17001:18001(1000) ack 1
+0.01 < . 1:1(0) ack 17001 win 65535 <sack 19001:20001,nop,nop>
+0.00 > . 18001:19001(1000) ack 1
+0.01 < . 1:1(0) ack 18001 win 65535 <sack 19001:20001,nop,nop>
+0.00 > F. 20001:20001(0) ack 1
+0.01 < . 1:1(0) ack 20001 win 65535
+0.00 > F. 20001:20001(0) ack 1
+0.1 < F. 1:1(0) ack 72002 win 65535
'''

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

This revision is now accepted and ready to land.Mar 17 2021, 4:00 PM