From 7ffe5bfb3c4bb21a09046e254a2b6a12e3450ada Mon Sep 17 00:00:00 2001 From: goldsimon Date: Thu, 9 Mar 2017 13:29:41 +0100 Subject: [PATCH] tcp: watch out for pcb->nrtx overflows and tcp_backoff indexing overflow --- src/core/tcp.c | 7 ++++--- src/core/tcp_out.c | 8 ++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/core/tcp.c b/src/core/tcp.c index 4eb55bf5..8c136817 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -1045,11 +1045,11 @@ tcp_slowtmr_start: pcb_remove = 0; pcb_reset = 0; - if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { + if (pcb->state == SYN_SENT && pcb->nrtx >= TCP_SYNMAXRTX) { ++pcb_remove; LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); } - else if (pcb->nrtx == TCP_MAXRTX) { + else if (pcb->nrtx >= TCP_MAXRTX) { ++pcb_remove; LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); } else { @@ -1083,7 +1083,8 @@ tcp_slowtmr_start: /* Double retransmission time-out unless we are trying to * connect to somebody (i.e., we are in SYN_SENT). */ if (pcb->state != SYN_SENT) { - pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; + u8_t backoff_idx = LWIP_MIN(pcb->nrtx, sizeof(tcp_backoff)-1); + pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[backoff_idx]; } /* Reset the retransmission timer. */ diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c index 44d52112..8fe136d2 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c @@ -1420,7 +1420,9 @@ tcp_rexmit_rto(struct tcp_pcb *pcb) pcb->unacked = NULL; /* increment number of retransmissions */ - ++pcb->nrtx; + if (pcb->nrtx < 0xFF) { + ++pcb->nrtx; + } /* Don't take any RTT measurements after retransmitting. */ pcb->rttest = 0; @@ -1465,7 +1467,9 @@ tcp_rexmit(struct tcp_pcb *pcb) } #endif /* TCP_OVERSIZE */ - ++pcb->nrtx; + if (pcb->nrtx < 0xFF) { + ++pcb->nrtx; + } /* Don't take any rtt measurements after retransmitting. */ pcb->rttest = 0;