From ae1c59f3a94c2e6f8d2ff0443cd96b74cc9b05bf Mon Sep 17 00:00:00 2001 From: Evgeny Date: Thu, 23 Apr 2026 01:38:17 +0300 Subject: [PATCH] Fix unaligned uint64_t access in packed struct causing garbage request_id - Changed request_id from uint64_t to uint32_t in BGP_PING_REQUEST/RESPONSE - Added uint16_t reserved field after subcmd for proper alignment - Updated next_ping_req_id from uint64_t to uint32_t in ROUTE_BGP - Fixed all log format strings from %016llx to %08x - All 26 tests passing --- src/route_bgp.h | 2 +- src/route_ping.c | 28 ++++++++++++++-------------- src/route_ping.h | 6 ++++-- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/route_bgp.h b/src/route_bgp.h index ecd205fe..817ca8c4 100644 --- a/src/route_bgp.h +++ b/src/route_bgp.h @@ -85,7 +85,7 @@ struct ROUTE_BGP { struct ll_queue* nodes; struct NODEINFO_Q* local_node; struct route_ping_pending* ping_pending; - uint64_t next_ping_req_id; + uint32_t next_ping_req_id; uint8_t allow_nat_check_local; // 1 = разрешить NAT check для локальных подсетей (для тестов) }; diff --git a/src/route_ping.c b/src/route_ping.c index ddc1acf2..9aec90fd 100644 --- a/src/route_ping.c +++ b/src/route_ping.c @@ -21,7 +21,7 @@ struct route_ping_series_ctx { struct ETCP_CONN* reply_conn; - uint64_t request_id; + uint32_t request_id; struct sockaddr_storage target_addr; uint8_t pubkey[SC_PUBKEY_SIZE]; struct ETCP_SOCKET* local_sock; @@ -37,7 +37,7 @@ struct route_ping_series_ctx { struct route_ping_pending { struct route_ping_pending* next; struct ROUTE_BGP* bgp; - uint64_t request_id; + uint32_t request_id; route_ping_callback_t callback; void* arg; void* timeout_timer; @@ -76,8 +76,8 @@ void route_ping_handle_resp(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, return; } const struct BGP_PING_RESPONSE* resp = (const struct BGP_PING_RESPONSE*)data; - DEBUG_INFO(DEBUG_CATEGORY_BGP, "from=%s request_id=%016llx sent=%u ok=%u avg_rtt=%u", - from_conn->log_name, (unsigned long long)resp->request_id, + DEBUG_INFO(DEBUG_CATEGORY_BGP, "from=%s request_id=%08x sent=%u ok=%u avg_rtt=%u", + from_conn->log_name, (unsigned)resp->request_id, (unsigned)resp->count_sent, (unsigned)resp->count_ok, (unsigned)resp->avg_rtt); struct route_ping_pending** cur = &bgp->ping_pending; @@ -98,8 +98,8 @@ void route_ping_handle_resp(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, } cur = &(*cur)->next; } - DEBUG_WARN(DEBUG_CATEGORY_BGP, "request_id=%016llx not found in pending list", - (unsigned long long)resp->request_id); + DEBUG_WARN(DEBUG_CATEGORY_BGP, "request_id=%08x not found in pending list", + (unsigned)resp->request_id); } void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { @@ -119,7 +119,7 @@ void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { struct nat_check_arg* na = (struct nat_check_arg*)p->arg; DEBUG_DEBUG(DEBUG_CATEGORY_BGP, " checking pending req_id=%016llx via=%s link->etcp=%s", - (unsigned long long)p->request_id, + (unsigned)p->request_id, p->via_conn ? p->via_conn->log_name : "NULL", (na && na->link && na->link->etcp) ? na->link->etcp->log_name : "NULL"); @@ -134,7 +134,7 @@ void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { u_free(p); cancelled++; DEBUG_INFO(DEBUG_CATEGORY_BGP, "cancel_for_conn: cancelled req_id=%016llx", - (unsigned long long)p->request_id); + (unsigned)p->request_id); } else { cur = &(*cur)->next; } @@ -207,8 +207,8 @@ int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, pending->timeout_timer = uasync_set_timeout(bgp->instance->ua, wait_timeout_ms * 10, pending, route_ping_pending_timeout, "route_ping"); - DEBUG_INFO(DEBUG_CATEGORY_BGP, "request_id=%016llx ip=%s port=%u pubkey=%s", - (unsigned long long)pending->request_id, + DEBUG_INFO(DEBUG_CATEGORY_BGP, "request_id=%08x ip=%s port=%u pubkey=%s", + (unsigned)pending->request_id, ip_to_str(&target_ip, AF_INET).str, (unsigned)target_port, pubkey ? "yes" : "no"); return 0; } @@ -241,9 +241,9 @@ static void route_ping_series_finish(struct route_ping_series_ctx* ctx) { e->len = sizeof(struct BGP_PING_RESPONSE); etcp_send(ctx->reply_conn, e); DEBUG_INFO(DEBUG_CATEGORY_BGP, - "PING series done %s request_id=%016llx sent=%u ok=%u avg_rtt=%u", + "PING series done %s request_id=%08x sent=%u ok=%u avg_rtt=%u", ctx->reply_conn->log_name, - (unsigned long long)ctx->request_id, + (unsigned)ctx->request_id, (unsigned)ctx->count_sent, (unsigned)ctx->count_ok, (unsigned)avg_rtt); @@ -366,8 +366,8 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp, } DEBUG_INFO(DEBUG_CATEGORY_BGP, - "PING series start request_id=%016llx target=%s:%u count=%u timeout=%u", - (unsigned long long)ctx->request_id, + "PING series start request_id=%08x target=%s:%u count=%u timeout=%u", + (unsigned)ctx->request_id, ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port), (unsigned)ctx->count_total, diff --git a/src/route_ping.h b/src/route_ping.h index 758ad886..c657a451 100644 --- a/src/route_ping.h +++ b/src/route_ping.h @@ -11,7 +11,8 @@ struct BGP_PING_REQUEST { uint8_t cmd; // ETCP_ID_ROUTE_ENTRY uint8_t subcmd; // ROUTE_SUBCMD_PING_REQ - uint64_t request_id; // для корреляции + uint16_t reserved; // padding для выравнивания request_id + uint32_t request_id; // для корреляции uint8_t count; // число пингов uint8_t socket_id; // id сокета пингуемого узла uint16_t interval_ms; // интервал между пингами @@ -24,7 +25,8 @@ struct BGP_PING_REQUEST { struct BGP_PING_RESPONSE { uint8_t cmd; uint8_t subcmd; // ROUTE_SUBCMD_PING_RESP - uint64_t request_id; + uint16_t reserved; // padding для выравнивания + uint32_t request_id; uint8_t count_sent; uint8_t count_ok; uint16_t avg_rtt; // средний RTT в 0.1ms