tcp: watch out for pcb->nrtx overflows and tcp_backoff indexing overflow

(cherry picked from commit 7ffe5bfb3c)
This commit is contained in:
goldsimon 2017-03-09 13:29:41 +01:00
parent 66db517a28
commit 19d56b4096
2 changed files with 10 additions and 5 deletions

View File

@ -1013,11 +1013,11 @@ tcp_slowtmr_start:
pcb_remove = 0; pcb_remove = 0;
pcb_reset = 0; pcb_reset = 0;
if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { if (pcb->state == SYN_SENT && pcb->nrtx >= TCP_SYNMAXRTX) {
++pcb_remove; ++pcb_remove;
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); 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; ++pcb_remove;
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
} else { } else {
@ -1051,7 +1051,8 @@ tcp_slowtmr_start:
/* Double retransmission time-out unless we are trying to /* Double retransmission time-out unless we are trying to
* connect to somebody (i.e., we are in SYN_SENT). */ * connect to somebody (i.e., we are in SYN_SENT). */
if (pcb->state != 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. */ /* Reset the retransmission timer. */

View File

@ -1420,7 +1420,9 @@ tcp_rexmit_rto(struct tcp_pcb *pcb)
pcb->unacked = NULL; pcb->unacked = NULL;
/* increment number of retransmissions */ /* increment number of retransmissions */
++pcb->nrtx; if (pcb->nrtx < 0xFF) {
++pcb->nrtx;
}
/* Don't take any RTT measurements after retransmitting. */ /* Don't take any RTT measurements after retransmitting. */
pcb->rttest = 0; pcb->rttest = 0;
@ -1465,7 +1467,9 @@ tcp_rexmit(struct tcp_pcb *pcb)
} }
#endif /* TCP_OVERSIZE */ #endif /* TCP_OVERSIZE */
++pcb->nrtx; if (pcb->nrtx < 0xFF) {
++pcb->nrtx;
}
/* Don't take any rtt measurements after retransmitting. */ /* Don't take any rtt measurements after retransmitting. */
pcb->rttest = 0; pcb->rttest = 0;