From 98d1cb1c000577468e2b1b54137b4bb37f161f85 Mon Sep 17 00:00:00 2001 From: Simon Goldschmidt Date: Mon, 12 Nov 2018 20:55:23 +0100 Subject: [PATCH] tcp_recved: fix overflow check Improved fix instead of patch #9699. Signed-off-by: Simon Goldschmidt --- src/core/tcp.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/core/tcp.c b/src/core/tcp.c index 0743eaf4..bd7d64ec 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -968,6 +968,7 @@ void tcp_recved(struct tcp_pcb *pcb, u16_t len) { u32_t wnd_inflation; + tcpwnd_size_t rcv_wnd; LWIP_ASSERT_CORE_LOCKED(); @@ -977,19 +978,13 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len) LWIP_ASSERT("don't call tcp_recved for listen-pcbs", pcb->state != LISTEN); - pcb->rcv_wnd = (tcpwnd_size_t)(pcb->rcv_wnd + len); - if (pcb->rcv_wnd > TCP_WND_MAX(pcb)) { + rcv_wnd = (tcpwnd_size_t)(pcb->rcv_wnd + len); + if ((rcv_wnd > TCP_WND_MAX(pcb)) || (rcv_wnd < pcb->rcv_wnd)) { + /* window got too big or tcpwnd_size_t overflow */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: window got too big or tcpwnd_size_t overflow\n")); pcb->rcv_wnd = TCP_WND_MAX(pcb); - } else if (pcb->rcv_wnd == 0) { - /* rcv_wnd overflowed */ - if (TCP_STATE_IS_CLOSING(pcb->state)) { - /* In passive close, we allow this, since the FIN bit is added to rcv_wnd - by the stack itself, since it is not mandatory for an application - to call tcp_recved() for the FIN bit, but e.g. the netconn API does so. */ - pcb->rcv_wnd = TCP_WND_MAX(pcb); - } else { - LWIP_ASSERT("tcp_recved: len wrapped rcv_wnd\n", 0); - } + } else { + pcb->rcv_wnd = rcv_wnd; } wnd_inflation = tcp_update_rcv_ann_wnd(pcb);