Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 2 Jul 2002 02:34:07 -0700 (PDT)
From:      Don Lewis <dl-freebsd@catspoiler.org>
To:        pavel@alum.mit.edu
Cc:        net@FreeBSD.ORG
Subject:   Re: questions about TCP RST validity
Message-ID:  <200207020934.g629Yh0M006533@gw.catspoiler.org>
In-Reply-To: <200207020353.g623rUR62985@scout.networkphysics.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On  1 Jul, Tom Pavel wrote:
> 
> Hi.  I'm confused about some code dealing with the acceptance of RSTs
> in tcp_input.c.  I've gleaned what I can about the history of that
> code through the CVS repository, but I'm still looking for some more
> insight.  The code in question requires that a RST have a sequence
> number within the current advertised window:
> 
>         if (thflags & TH_RST) {
>                 if (SEQ_GEQ(th->th_seq, tp->last_ack_sent) &&
>                     SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) {
>                         switch (tp->t_state) {
> 
>                         case TCPS_SYN_RECEIVED:
>                         ...
>                         }
>                 }
>                 goto drop;
>         }
> 
> 
> This is all well and good.  It follows RFC793 which says:
> 
>     In all states except SYN-SENT, all reset (RST) segments are validated
>     by checking their SEQ-fields.  A reset is valid if its sequence number
>     is in the window.  
> 
> This prevents DoS attacks by requiring an intruder to guess a seqnum
> within the current window.  (The code appeared with revs 1.81 and
> 1.98, responding to PR kern/7892 which concerned such DoS attacks.)
> 
> However, it seems to ignore the possibility that the RST and an ACK
> updating the advertised window might cross in flight.  RFC793 also
> requires that RSTs set their seqnum from the ACK field of the pkt they
> are responding to, even if the sender knows it has sent a seqnum
> beyond that ACK (like the FIN below).

If the implementation sending a RST isn't broken, the case of the RST
and ACK crossing in flight is handled by sending another RST with an
updated sequence number from the ACK that was received after the initial
RST was sent, which the initial RST crossed in flight.


> Here is a trace to illustrate:
> 
> 09:05:35.214014 BB.61390 > AA.80: S 2597110672:2597110672(0) win 65535 <mss 1460,nop,wscale 0,nop,nop,timestamp 3845318 0>
> 09:05:35.214310 AA.80 > BB.61390: S 3568521185:3568521185(0) ack 2597110673 win 4380 <mss 1460> (DF)
> 09:05:35.277441 BB.61390 > AA.80: . ack 3568521186 win 65535
> 09:05:35.278316 BB.61390 > AA.80: P 2597110673:2597111260(587) ack 3568521186 win 65535
> 09:05:35.302557 AA.80 > BB.61390: P 3568521186:3568522646(1460) ack 2597111260 win 4380 (DF)
> 09:05:35.302659 AA.80 > BB.61390: P 3568522646:3568524106(1460) ack 2597111260 win 4380 (DF)
> 09:05:35.302762 AA.80 > BB.61390: P 3568524106:3568525566(1460) ack 2597111260 win 4380 (DF)
> 09:05:35.380157 BB.61390 > AA.80: . ack 3568524106 win 64240
> 09:05:35.380211 AA.80 > BB.61390: . 3568525566:3568527026(1460) ack 2597111260 win 4380 (DF)
> 09:05:35.380231 AA.80 > BB.61390: . 3568527026:3568528486(1460) ack 2597111260 win 4380 (DF)
> 09:05:35.380248 AA.80 > BB.61390: . 3568528486:3568529946(1460) ack 2597111260 win 4380 (DF)
> 09:05:35.451495 BB.61390 > AA.80: . ack 3568527026 win 64240
> 09:05:35.451537 AA.80 > BB.61390: . 3568529946:3568531406(1460) ack 2597111260 win 4380 (DF)
> 09:05:35.451552 AA.80 > BB.61390: . 3568531406:3568532866(1460) ack 2597111260 win 4380 (DF)
> 09:05:35.451571 AA.80 > BB.61390: . 3568532866:3568534326(1460) ack 2597111260 win 4380 (DF)
> 09:05:35.453172 BB.61390 > AA.80: . ack 3568529946 win 62780
> 09:05:35.453206 AA.80 > BB.61390: . 3568534326:3568535786(1460) ack 2597111260 win 4380 (DF)
> 09:05:35.453221 AA.80 > BB.61390: . 3568535786:3568537246(1460) ack 2597111260 win 4380 (DF)
> 09:05:35.453976 BB.61390 > AA.80: F 2597111260:2597111260(0) ack 3568529946 win 65535
> 09:05:35.454002 AA.80 > BB.61390: . 3568537246:3568537538(292) ack 2597111261 win 4380 (DF)
> 09:05:35.518444 BB.61390 > AA.80: R 2597111260:2597111260(0) win 0

It looks like BB is broken.  From the timestamps above, it looks like
there is about a 60 ms RTT between AA and BB.  If so, it sure looks like
BB is sending the RST in response to the ACK 2597111261 from AA, but why
is it using the wrong sequence number?  It shouldn't be sending the RST
in response to one of the earlier data packets from AA, since BB acked
that data in the FIN packet that it sent.  I suppose BB could have sent
the RST unsolicited, but why did it wait what looks like a RTT delay
time after sending the FIN?

> Now, it seems to me that one could argue that the fault is entirely on
> BB, who fails to respond with RST to all the pkts sent after the
> initial RST.  I imagine that this could be caused by some sort of
> stateful firewall, or perhaps by BB hanging up a dialup connection.
> This case is alluded to in the tcp_input.c comments:
> 
>      * If we have multiple segments in flight, the intial reset
>      * segment sequence numbers will be to the left of last_ack_sent,
>      * but they will eventually catch up.

This comment is covers the case of the initial outgoing RST passing
incoming ACK packets in flight.  The only way of handling the modem
being hung up is to time out the connection.

BTW, if stateful firewalls don't send RST packets in response to
incoming TCP packets that don't correspond to valid connections, it is
much easier to spoof a connection to an outside host that looks like it
is coming from the firewall.

> In any event, though, it seems to me relatively harmless to have AA
> accept seqnums "slightly" to the left of its current advertised window
> (say last_ack_sent - rcv_wnd).  This would save a bunch of needless
> retransmits and it would clean up the control block much sooner than
> letting AA timeout on retransmitting.

This doesn't help in the above example if the initial RST is lost due to
network congestion or other types of packet loss on the network.  If
only one RST is sent and it gets dropped before the other end of the
connection sees it, we've still got the same problem.  Increasing the
size of the acceptable RST window increases the vulnerability to DoS
attacks proportionally.


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200207020934.g629Yh0M006533>