lwip-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-devel] [bug #50837] LWIP TCP/IP race condition


From: Joel Cunningham
Subject: [lwip-devel] [bug #50837] LWIP TCP/IP race condition
Date: Fri, 21 Apr 2017 09:31:05 -0400 (EDT)
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30

Follow-up Comment #7, bug #50837 (project lwip):

preet,

I took a look at your wireshark capture and I have a new idea what's going on.
 You're not encountering a zero-window situation, instead the server stops
ACKing new data.  You can see this starting on packet 349 where the client is
retransmitting the same packet with SEQ = 1457 (wireshark relative numbering)

Combine this with the report of mbox errors and what I think is happening is
that your mbox implementation can't handle a full window's worth of data
according to the segmentation from the client.  Once the recvmbox is full and
your application is not draining it, LwIP has a feature called "refused data"
where it stops accepting new data, and won't issue any ACKS.  Search the code
for pcb->refused_data.  The refused data situation can be resolved by having
your application read data or increasing your mbox to accommodate a full
windows worth of data

Then the client tries to issue a RST at packet 378 and the server issues an
ACK in response.  I believe this is because the client is using SEQ = 2097 but
since we've been dropping data, pcb->rcv_nxt is at 1457.  See the below code
segment in tcp_process:


/* Process incoming RST segments. */
  if (flags & TCP_RST) {
    /* First, determine if the reset is acceptable. */
    if (pcb->state == SYN_SENT) {
      /* "In the SYN-SENT state (a RST received in response to an initial
SYN),
          the RST is acceptable if the ACK field acknowledges the SYN." */
      if (ackno == pcb->snd_nxt) {
        acceptable = 1;
      }
    } else {
      /* "In all states except SYN-SENT, all reset (RST) segments are
validated
          by checking their SEQ-fields." */
      if (seqno == pcb->rcv_nxt) {
        acceptable = 1;
      } else  if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
                                  pcb->rcv_nxt + pcb->rcv_wnd)) {
        /* If the sequence number is inside the window, we only send an ACK
           and wait for a re-send with matching sequence number.
           This violates RFC 793, but is required to protection against
           CVE-2004-0230 (RST spoofing attack). */
        tcp_ack_now(pcb);
      }
    }


acceptable is not being set to 1 and this basically means the RST did not
reset the connection.  The client never attempted again to send a RST with SEQ
= 1457, so the connection enters a zombie state

    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/bugs/?50837>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.nongnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]