From 3959ed8afe3b37538343ae034e58bae48c670033 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Thu, 23 Apr 2026 01:59:41 +0300 Subject: [PATCH] Fix use-after-free: read request_id before etcp_send frees req_pkt req_pkt memory could be freed by etcp_send callback before pending->request_id was assigned. Store request_id in local variable and use it for pending. --- src/route_ping.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/route_ping.c b/src/route_ping.c index d1558101..6abb6b63 100644 --- a/src/route_ping.c +++ b/src/route_ping.c @@ -100,19 +100,6 @@ void route_ping_handle_resp(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, } DEBUG_WARN(DEBUG_CATEGORY_BGP, "request_id=%08x not found in pending list", (unsigned)resp->request_id); - // Dump all pending entries for debugging - struct route_ping_pending* dump_cur = bgp->ping_pending; - int dump_count = 0; - while (dump_cur) { - DEBUG_WARN(DEBUG_CATEGORY_BGP, " pending[%d]: request_id=%08x via=%s", - dump_count, (unsigned)dump_cur->request_id, - dump_cur->via_conn ? dump_cur->via_conn->log_name : "NULL"); - dump_cur = dump_cur->next; - dump_count++; - } - if (dump_count == 0) { - DEBUG_WARN(DEBUG_CATEGORY_BGP, " pending list is EMPTY"); - } } void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { @@ -179,8 +166,6 @@ int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, req_pkt->subcmd = ROUTE_SUBCMD_PING_REQ; uint32_t new_req_id = bgp->next_ping_req_id++; req_pkt->request_id = new_req_id; - DEBUG_TRACE(DEBUG_CATEGORY_BGP, "assigned request_id=%08x (next was %08x)", - (unsigned)new_req_id, (unsigned)(new_req_id + 1)); req_pkt->count = count; req_pkt->interval_ms = interval_ms; req_pkt->timeout_ms = timeout_ms; @@ -214,9 +199,7 @@ int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, return -5; } pending->bgp = bgp; - pending->request_id = req_pkt->request_id; - DEBUG_TRACE(DEBUG_CATEGORY_BGP, "pending stored request_id=%08x (from req_pkt=%08x)", - (unsigned)pending->request_id, (unsigned)req_pkt->request_id); + pending->request_id = new_req_id; // req_pkt may be freed by etcp_send callback pending->callback = cb; pending->arg = arg; pending->via_conn = to_conn;