[Bug 230755] natd sends wrong sequence number when a retransmitted PASV packet comes in

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Fri Dec 11 17:05:54 UTC 2020


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=230755

longwitz at incore.de changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |longwitz at incore.de

--- Comment #1 from longwitz at incore.de ---
The patch given in this bug report waits for commit.

I like to describe some technical background for the problem.
Relevant are the functions AddSeq() and GetDeltaSeqOut() in
the source alias_db.c. AddSeq() start with the following
comment:

When a TCP packet has been altered in length, save this
information in a circular list.  If enough packets have
been altered, then this list will begin to overwrite itself.

The important word here is "circular". The used list has
N_LINK_TCP_DATA (=3) entries and AddSeq() writes to the
list circual from top to bottom and holds the actual index
of the list in the variable lnk->data.tcp->state.index.

The function GetDeltaSeqOut() starts with the following
comment:

Find out how much the sequence number has been altered for an outgoing
TCP packet.  To do this, a circular list of ACK numbers where the TCP
packet size was altered is searched.

The circular list read by GetDeltaSeqOut() is the same list
filled by AddSeq() in a circular manner before. But the function
GetDeltaSeqOut() does not read the list in a circular way but
sequential from top to bottom. Especially GetDeltaSeqOut() does
not use the variable lnk->data.tcp->state.index in any way.

That is the leak !

Example:
If a "227 Entering Passive Mode" packet must be retransmittet
and the length changes from 51 to 50, then we have three cases
for the list:

  case 1:  index 0:   original packet        51
           index 1:   retransmitted packet   50
           index 2:   not relevant

  case 2:  index 0:   not relevant
           index 1:   original packet        51
           index 2:   retransmitted packet   50

  case 3:  index 0:   retransmitted packet   50
           index 1:   not relevant
           index 2:   original packet        51

Only in case 3 the function GetDeltaSeqOut() finds the correct
length 50, in case 1 and 2 GetDeltaSeqOut() finds length 51
and TCP fails.

Exactly this problem is solved by the patch given in this bug
report for GetDeltaSeqOut() and (identical constellation)
GetDeltaAckIn(). The function GetDeltaSeqOut() with the patch
included searches the list from bottom to top and starts
with the correct index lnk->data.tcp->state.index.

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-ipfw mailing list