diff --git a/CHANGELOG b/CHANGELOG index 26d49ecf..cb961dd3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -117,6 +117,9 @@ HISTORY ++ Bugfixes: + 2014-09-02: Simon Goldschmidt + * tcp.c: fixed bug #42299 tcp_abort() leaves freed pcb on tcp_bound_pcbs list + 2014-08-20: Simon Goldschmidt * dns.c: fixed bug #42987 lwIP is vulnerable to DNS cache poisoning due to non-randomized TXIDs diff --git a/src/core/tcp.c b/src/core/tcp.c index f89409c0..7ecfeddd 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -382,14 +382,19 @@ tcp_abandon(struct tcp_pcb *pcb, int reset) errf = pcb->errf; #endif /* LWIP_CALLBACK_API */ errf_arg = pcb->callback_arg; - TCP_PCB_REMOVE_ACTIVE(pcb); + if ((pcb->state == CLOSED) && (pcb->local_port != 0)) { + /* bound, not yet opened */ + TCP_RMV(&tcp_bound_pcbs, pcb); + } else { + TCP_PCB_REMOVE_ACTIVE(pcb); + } if (pcb->unacked != NULL) { tcp_segs_free(pcb->unacked); } if (pcb->unsent != NULL) { tcp_segs_free(pcb->unsent); } -#if TCP_QUEUE_OOSEQ +#if TCP_QUEUE_OOSEQ if (pcb->ooseq != NULL) { tcp_segs_free(pcb->ooseq); } @@ -1634,7 +1639,7 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) TCP_RMV(pcblist, pcb); tcp_pcb_purge(pcb); - + /* if there is an outstanding delayed ACKs, send it */ if (pcb->state != TIME_WAIT && pcb->state != LISTEN && @@ -1652,6 +1657,8 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) } pcb->state = CLOSED; + /* reset the local port to prevent the pcb from being 'bound' */ + pcb->local_port = 0; LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); }