1195972f6Sopenharmony_ciFrom adbc5b5f716d108966bcf606e61de60b83f525a5 Mon Sep 17 00:00:00 2001
2195972f6Sopenharmony_ciFrom: Simon Goldschmidt <goldsimon@gmx.de>
3195972f6Sopenharmony_ciDate: Thu, 5 Mar 2020 21:20:35 +0100
4195972f6Sopenharmony_ciSubject: [PATCH] tcp: tighten up checks for received SYN
5195972f6Sopenharmony_ciAny malicous segment could contain a SYN up to now (no check).
6195972f6Sopenharmony_ciA SYN in the wrong segment could break OOSEQ queueing.
7195972f6Sopenharmony_ciFix this by allowing SYN only in states where it is required.
8195972f6Sopenharmony_ciSee bug #56397: Assert "tcp_receive: ooseq tcplen > rcv_wnd"
9195972f6Sopenharmony_ciSigned-off-by: Simon Goldschmidt <goldsimon@gmx.de>
10195972f6Sopenharmony_ciConflict: NA
11195972f6Sopenharmony_ciReference: https://git.savannah.gnu.org/cgit/lwip.git/commit/?id=adbc5b5f716d108966bcf606e61de60b83f525a5
12195972f6Sopenharmony_ci---
13195972f6Sopenharmony_ci src/core/tcp_in.c | 17 +++++++++++++----
14195972f6Sopenharmony_ci 1 file changed, 13 insertions(+), 4 deletions(-)
15195972f6Sopenharmony_cidiff --git a/src/core/tcp_in.c b/src/core/tcp_in.c
16195972f6Sopenharmony_ciindex 4bfba85f..90061281 100644
17195972f6Sopenharmony_ci--- a/src/core/tcp_in.c
18195972f6Sopenharmony_ci+++ b/src/core/tcp_in.c
19195972f6Sopenharmony_ci@@ -852,6 +852,13 @@ tcp_process(struct tcp_pcb *pcb)
20195972f6Sopenharmony_ci 
21195972f6Sopenharmony_ci   tcp_parseopt(pcb);
22195972f6Sopenharmony_ci 
23195972f6Sopenharmony_ci+  if (flags & TCP_SYN) {
24195972f6Sopenharmony_ci+    /* accept SYN only in 2 states: */
25195972f6Sopenharmony_ci+    if ((pcb->state != SYN_SENT) && (pcb->state != SYN_RCVD)) {
26195972f6Sopenharmony_ci+      return ERR_OK;
27195972f6Sopenharmony_ci+    }
28195972f6Sopenharmony_ci+  }
29195972f6Sopenharmony_ci+
30195972f6Sopenharmony_ci   /* Do different things depending on the TCP state. */
31195972f6Sopenharmony_ci   switch (pcb->state) {
32195972f6Sopenharmony_ci     case SYN_SENT:
33195972f6Sopenharmony_ci@@ -924,7 +931,12 @@ tcp_process(struct tcp_pcb *pcb)
34195972f6Sopenharmony_ci       }
35195972f6Sopenharmony_ci       break;
36195972f6Sopenharmony_ci     case SYN_RCVD:
37195972f6Sopenharmony_ci-      if (flags & TCP_ACK) {
38195972f6Sopenharmony_ci+      if (flags & TCP_SYN) {
39195972f6Sopenharmony_ci+        if (seqno == pcb->rcv_nxt - 1) {
40195972f6Sopenharmony_ci+          /* Looks like another copy of the SYN - retransmit our SYN-ACK */
41195972f6Sopenharmony_ci+          tcp_rexmit(pcb);
42195972f6Sopenharmony_ci+        }
43195972f6Sopenharmony_ci+      } else if (flags & TCP_ACK) {
44195972f6Sopenharmony_ci         /* expected ACK number? */
45195972f6Sopenharmony_ci         if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) {
46195972f6Sopenharmony_ci           pcb->state = ESTABLISHED;
47195972f6Sopenharmony_ci@@ -975,9 +987,6 @@ tcp_process(struct tcp_pcb *pcb)
48195972f6Sopenharmony_ci           tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
49195972f6Sopenharmony_ci                   ip_current_src_addr(), tcphdr->dest, tcphdr->src);
50195972f6Sopenharmony_ci         }
51195972f6Sopenharmony_ci-      } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
52195972f6Sopenharmony_ci-        /* Looks like another copy of the SYN - retransmit our SYN-ACK */
53195972f6Sopenharmony_ci-        tcp_rexmit(pcb);
54195972f6Sopenharmony_ci       }
55195972f6Sopenharmony_ci       break;
56195972f6Sopenharmony_ci     case CLOSE_WAIT:
57195972f6Sopenharmony_ci-- 
58195972f6Sopenharmony_ci2.28.0.windows.1
59