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