From 0c8de3db8420ccefb1b191af0dcfa3ad4fab5b6f Mon Sep 17 00:00:00 2001 From: Evgeny Date: Thu, 4 Jun 2026 00:13:28 +0300 Subject: [PATCH] fix: double-free in tcp_proxy_server_conn_free via freed flag error_cb can fire twice for the same fd in one epoll batch, or conn_free called from multiple callbacks during restart/shutdown. freed flag makes conn_free idempotent. --- src/proxy/tcp_proxy_server.c | 2 ++ src/proxy/tcp_proxy_server.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/proxy/tcp_proxy_server.c b/src/proxy/tcp_proxy_server.c index 24978ead..5f48d412 100644 --- a/src/proxy/tcp_proxy_server.c +++ b/src/proxy/tcp_proxy_server.c @@ -196,6 +196,8 @@ static int conn_total(struct tcp_proxy_server_conn* rc) { void tcp_proxy_server_conn_free(struct tcp_proxy_server_conn* rc) { if (!rc) return; + if (rc->freed) return; + rc->freed = 1; int total = conn_total(rc); DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:FREE fd=%d sid=%08x total=%d cli_closed=%d fin=%d error=%d", rc->tc ? (int)rc->tc->sock : -1, rc->stream_id, total, rc->cli_closed, rc->tc ? rc->tc->fin : 0, rc->tc ? rc->tc->error : 0); diff --git a/src/proxy/tcp_proxy_server.h b/src/proxy/tcp_proxy_server.h index 64f2520b..14db2290 100644 --- a/src/proxy/tcp_proxy_server.h +++ b/src/proxy/tcp_proxy_server.h @@ -35,6 +35,7 @@ struct tcp_proxy_server_conn { void* close_timer; // таймер повтора CLOSE/ERROR int close_backoff; // backoff: 50..5000 tb (5ms..500ms) void* diag_timer; // 1-секундный таймер диагностики + uint8_t freed; // 1 = уже освобождён, защита от double-free struct queue_waiter_handle pause_waiter; struct UASYNC* ua;