diff --git a/lib/memory_pool.c b/lib/memory_pool.c index 30581eff..afdd8f4d 100644 --- a/lib/memory_pool.c +++ b/lib/memory_pool.c @@ -141,3 +141,14 @@ void memory_pool_destroy(struct memory_pool* pool) { pool->free_count = 0; u_free(pool); } + +int memory_pool_is_freed(struct memory_pool* pool, void* obj) +{ + if (!pool || !obj) return 0; + void* cur = pool->free_head; + while (cur) { + if (cur == obj) return 1; + cur = *(void**)cur; + } + return 0; +} diff --git a/lib/memory_pool.h b/lib/memory_pool.h index 268cdec8..7391344a 100644 --- a/lib/memory_pool.h +++ b/lib/memory_pool.h @@ -34,4 +34,6 @@ size_t memory_pool_get_total_free_blocks(void); #define memory_pool_alloc(pool) memory_pool_alloc_impl(pool, PLOCATION) #define memory_pool_free(pool, obj) memory_pool_free_impl(pool, obj, PLOCATION) +int memory_pool_is_freed(struct memory_pool* pool, void* obj); + #endif // MEMORY_POOL_H diff --git a/src/etcp.c b/src/etcp.c index 8eee94b4..361470ff 100644 --- a/src/etcp.c +++ b/src/etcp.c @@ -16,6 +16,7 @@ #include // For bandwidth calcs #include // For UINT16_MAX #include "../lib/mem.h" +#include "../lib/memory_pool.h" // Enable comprehensive debug output for ETCP module #define DEBUG_CATEGORY_ETCP_DETAILED 1 @@ -1277,6 +1278,10 @@ void etcp_ack_recv(struct ETCP_CONN* etcp, uint32_t seq, uint16_t ts, uint16_t d void etcp_conn_input(struct ETCP_DGRAM* pkt) { DEBUG_TRACE(DEBUG_CATEGORY_ETCP, ""); if (!pkt) return; + if (memory_pool_is_freed(pkt->link->etcp->instance->pkt_pool, pkt)) { + DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "etcp_conn_input: pkt=%p ALREADY FREED in pkt_pool — HALTING", (void*)pkt); + volatile int _halt = 1; while (_halt) {} + } if (!pkt->data_len) { memory_pool_free(pkt->link->etcp->instance->pkt_pool, pkt); return; diff --git a/src/etcp_connections.c b/src/etcp_connections.c index 6be1298a..0b8be32a 100644 --- a/src/etcp_connections.c +++ b/src/etcp_connections.c @@ -1730,8 +1730,13 @@ process_decrypted: // log_dump("RECV decrypted:", pkt->data, pkt->data_len, link); - if (link->link_state == 3) etcp_conn_input(pkt); - else memory_pool_free(e_sock->instance->pkt_pool, pkt); + if (link->link_state == 3) { + if (memory_pool_is_freed(e_sock->instance->pkt_pool, pkt)) { + DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "etcp_conn_input: pkt=%p ALREADY FREED in pkt_pool — HALTING", (void*)pkt); + volatile int _halt = 1; while (_halt) {} + } + etcp_conn_input(pkt); + } else memory_pool_free(e_sock->instance->pkt_pool, pkt); return; ec_fr: diff --git a/src/lwip_tcp/lwip_tcp.c b/src/lwip_tcp/lwip_tcp.c index 5e5cb432..ef6f9515 100644 --- a/src/lwip_tcp/lwip_tcp.c +++ b/src/lwip_tcp/lwip_tcp.c @@ -790,9 +790,12 @@ void tcp_slowtmr(struct lwip_tcp_ctx *ctx) pcb = ctx->tw_pcbs; while (pcb != NULL) { if (!pcb->ctx) { - DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS DANGLING pcb=%p ctx=NULL in tcp_slowtmr, clearing tw_pcbs", (void*)pcb); - ctx->tw_pcbs = NULL; - break; + DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS DANGLING pcb=%p ctx=NULL in tcp_slowtmr — HALTING", (void*)pcb); + volatile int _halt = 1; while (_halt) {} + } + if (memory_pool_is_freed(pcb->ctx->pcb_pool, pcb)) { + DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS DANGLING pcb=%p IS FREED in tcp_slowtmr — HALTING", (void*)pcb); + volatile int _halt = 1; while (_halt) {} } pcb_remove = 0; @@ -1033,9 +1036,12 @@ static void tcp_kill_timewait(struct lwip_tcp_ctx *ctx) inactive = NULL; for (pcb = ctx->tw_pcbs; pcb != NULL; pcb = pcb->next) { if (!pcb->ctx) { - DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS DANGLING pcb=%p ctx=NULL in tcp_kill_timewait, clearing tw_pcbs", (void*)pcb); - ctx->tw_pcbs = NULL; - return; + DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS DANGLING pcb=%p ctx=NULL in tcp_kill_timewait — HALTING", (void*)pcb); + volatile int _halt = 1; while (_halt) {} + } + if (memory_pool_is_freed(pcb->ctx->pcb_pool, pcb)) { + DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS DANGLING pcb=%p IS FREED in tcp_kill_timewait — HALTING", (void*)pcb); + volatile int _halt = 1; while (_halt) {} } if ((uint32_t)(ctx->ticks - pcb->tmr) >= inactivity) { inactivity = ctx->ticks - pcb->tmr; @@ -1103,18 +1109,6 @@ struct tcp_pcb *tcp_alloc(struct lwip_tcp_ctx *ctx, uint8_t prio) if (pcb != NULL) { memset(pcb, 0, sizeof(struct tcp_pcb)); -#ifdef DEBUG - { - struct tcp_pcb *_tmp; - for (_tmp = ctx->tw_pcbs; _tmp; _tmp = _tmp->next) { - if (_tmp == pcb) { - DEBUG_ERROR(DEBUG_CATEGORY_ALL, "tcp_alloc: REUSED PCB %p STILL IN tw_pcbs! halting for debug", (void*)pcb); - volatile int _halt = 1; - while (_halt) {} - } - } - } -#endif pcb->prio = prio; pcb->ctx = ctx; pcb->snd_buf = TCP_SND_BUF; diff --git a/src/lwip_tcp/lwip_tcp_in.c b/src/lwip_tcp/lwip_tcp_in.c index b62f7ca7..9b1cbdf9 100644 --- a/src/lwip_tcp/lwip_tcp_in.c +++ b/src/lwip_tcp/lwip_tcp_in.c @@ -211,10 +211,14 @@ void lwip_tcp_input(struct lwip_tcp_ctx *ctx, struct pbuf *p, if (pcb == NULL) { for (pcb = ctx->tw_pcbs; pcb != NULL; pcb = pcb->next) { if (!pcb->ctx) { - DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS DANGLING pcb=%p ctx=NULL in lwip_tcp_input, clearing tw_pcbs", (void*)pcb); - ctx->tw_pcbs = NULL; + DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS DANGLING pcb=%p ctx=NULL in lwip_tcp_input — HALTING", (void*)pcb); pbuf_free(p); - return; + volatile int _halt = 1; while (_halt) {} + } + if (memory_pool_is_freed(pcb->ctx->pcb_pool, pcb)) { + DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS DANGLING pcb=%p IS FREED in lwip_tcp_input — HALTING", (void*)pcb); + pbuf_free(p); + volatile int _halt = 1; while (_halt) {} } if (pcb->remote_port == sport && pcb->local_port == dport &&