diff --git a/CHANGELOG b/CHANGELOG index a350b06f..59fc4bdc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -216,6 +216,10 @@ HISTORY ++ Bugfixes: + 2015-03-21: Simon Goldschmidt + * tcp_impl.h, tcp.c, tcp_in.c: fixed bug #41318 (Bad memory ref in tcp_input() + after tcp_close()) + 2015-03-21: Simon Goldschmidt * tcp_in.c: fixed bug #38468 (tcp_sent() not called on half-open connection for data ACKed with the same ack as FIN) diff --git a/src/core/tcp.c b/src/core/tcp.c index 36afd457..ab042ee1 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -193,7 +193,12 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) TCP_REG(&tcp_tw_pcbs, pcb); } else { /* CLOSE_WAIT: deallocate the pcb since we already sent a RST for it */ - memp_free(MEMP_TCP_PCB, pcb); + if (tcp_input_pcb == pcb) { + /* prevent using a deallocated pcb: free it from tcp_input later */ + tcp_trigger_input_pcb_close(); + } else { + memp_free(MEMP_TCP_PCB, pcb); + } } return ERR_OK; } diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index cd2a3b9b..ee2d6b99 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -1767,4 +1767,10 @@ tcp_parseopt(struct tcp_pcb *pcb) } } +void +tcp_trigger_input_pcb_close(void) +{ + recv_flags |= TF_CLOSED; +} + #endif /* LWIP_TCP */ diff --git a/src/include/lwip/tcp_impl.h b/src/include/lwip/tcp_impl.h index ada8b2c3..5a8c00de 100644 --- a/src/include/lwip/tcp_impl.h +++ b/src/include/lwip/tcp_impl.h @@ -497,6 +497,7 @@ u32_t tcp_next_iss(void); err_t tcp_keepalive(struct tcp_pcb *pcb); err_t tcp_zero_window_probe(struct tcp_pcb *pcb); +void tcp_trigger_input_pcb_close(void); #if TCP_CALCULATE_EFF_SEND_MSS u16_t tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest