fix: swap queue_entry_free/queue_dgram_free order in 27 places — prevents UAF when dgram_free accesses freed entry

uasync: replace raw socket_node* handle with packed index — fixes UAF after socket_array realloc
tcp_io: defer u_free in tcp_conn_destroy via uasync_call_soon — prevents callback-chain UAF
tcp_io: guard read_cb/write_cb with NULL queue checks after deferred destroy
tcp_io: save read_queue to local before queue_data_put + NULL guard after
route_connectivity: linked-list probe_ctx — cancel all parallel probes before nq free
This commit is contained in:
Evgeny committed 2026-07-02 17:14:38 +03:00
1 parent 8962f58ea4
commit 42d96f118d
9 files changed
+25 -25

No files matched your search

+7 -7
View File
@@ -105,7 +105,7 @@ static struct ETCP_CONN* first_conn(struct UTUN_INSTANCE* inst) {
static void srv_handler(struct ETCP_CONN* conn, struct ll_entry* entry) {
(void)conn;
if (!entry || !entry->dgram || entry->len < 10) { // svc_id(1) + subcmd(1) + seq(4) + data_len(4)
if (entry) { queue_entry_free(entry); queue_dgram_free(entry); }
if (entry) { queue_dgram_free(entry); queue_entry_free(entry); }
return;
}
uint8_t subcmd = entry->dgram[1];
@@ -123,7 +123,7 @@ static void srv_handler(struct ETCP_CONN* conn, struct ll_entry* entry) {
} else {
fwd_rcvd++;
}
queue_entry_free(entry); queue_dgram_free(entry);
queue_dgram_free(entry); queue_entry_free(entry);
// Send reply back
if (!g_test_done && reply_sent < TOTAL_PACKETS) {
@@ -139,7 +139,7 @@ static void srv_handler(struct ETCP_CONN* conn, struct ll_entry* entry) {
etcp_route_send(srv, client_node_id, re, 0); reply_sent++; }
}
} else {
queue_entry_free(entry); queue_dgram_free(entry);
queue_dgram_free(entry); queue_entry_free(entry);
}
}
@@ -147,7 +147,7 @@ static void srv_handler(struct ETCP_CONN* conn, struct ll_entry* entry) {
static void cli_handler(struct ETCP_CONN* conn, struct ll_entry* entry) {
(void)conn;
if (!entry || !entry->dgram || entry->len < 10) {
if (entry) { queue_entry_free(entry); queue_dgram_free(entry); }
if (entry) { queue_dgram_free(entry); queue_entry_free(entry); }
return;
}
uint8_t subcmd = entry->dgram[1];
@@ -166,7 +166,7 @@ static void cli_handler(struct ETCP_CONN* conn, struct ll_entry* entry) {
reply_rcvd++;
}
}
queue_entry_free(entry); queue_dgram_free(entry);
queue_dgram_free(entry); queue_entry_free(entry);
}
// ======================== Loopback test (no ETCP) ========================
@@ -178,7 +178,7 @@ static void loop_handler(struct ETCP_CONN* conn, struct ll_entry* entry) {
loop_rcvd++;
if (entry->dgram[1] == 0xAA && entry->dgram[2] == 0xBB && entry->dgram[3] == 0xCC) loop_ok = 1;
}
if (entry) { queue_entry_free(entry); queue_dgram_free(entry); }
if (entry) { queue_dgram_free(entry); queue_entry_free(entry); }
}
static int test_loopback(void) {
@@ -250,7 +250,7 @@ static void monitor(void* arg) {
struct ll_entry* e = queue_entry_new(0);
if (e) { e->dgram = u_malloc(10 + data_len); memcpy(e->dgram, buf, 10 + data_len); e->len = 10 + data_len;
if (etcp_route_send(cli, server_node_id, e, 0) == 0) fwd_sent++;
else { queue_entry_free(e); queue_dgram_free(e); }
else { queue_dgram_free(e); queue_entry_free(e); }
}
}
+1 -1
View File
@@ -48,7 +48,7 @@ static void test_handler(struct ETCP_CONN* conn, struct ll_entry* entry) {
return;
}
if (entry->dgram[1] != rx.marker) { rx.errors++; } else { rx.delivered++; rx.last_seq = rx.expected_seq; rx.expected_seq++; }
queue_entry_free(entry); queue_dgram_free(entry);
queue_dgram_free(entry); queue_entry_free(entry);
}
static void rx_reset(uint8_t marker) {
+2 -2
View File
@@ -85,7 +85,7 @@ static void* g_to_id = NULL;
static void cli_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
(void)conn;
if (!entry || !entry->dgram || entry->len < ICMP_PROXY_HDR_SIZE + 1) {
if (entry) { queue_entry_free(entry); queue_dgram_free(entry); } return;
if (entry) { queue_dgram_free(entry); queue_entry_free(entry); } return;
}
if (entry->dgram[1] == ICMP_PROXY_SUBCMD_REPLY) {
uint16_t rid, rseq;
@@ -105,7 +105,7 @@ static void cli_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
g_done = -1;
}
}
queue_entry_free(entry); queue_dgram_free(entry);
queue_dgram_free(entry); queue_entry_free(entry);
}
static void monitor(void* arg) {
+2 -2
View File
@@ -95,7 +95,7 @@ static void udp_echo_cb(socket_t sock, void* arg) {
static void cli_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
(void)conn;
if (!entry || !entry->dgram || entry->len < UDP_PROXY_HDR_SIZE + 1) {
if (entry) { queue_entry_free(entry); queue_dgram_free(entry); } return;
if (entry) { queue_dgram_free(entry); queue_entry_free(entry); } return;
}
// svc_id(1) + subcmd(1) + sender_node_id(8) + src_ip(4) + src_port(2) + dst_ip(4) + dst_port(2) + payload
size_t payload_len = entry->len - UDP_PROXY_HDR_SIZE;
@@ -108,7 +108,7 @@ static void cli_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
g_done = -1;
}
}
queue_entry_free(entry); queue_dgram_free(entry);
queue_dgram_free(entry); queue_entry_free(entry);
}
static void monitor(void* arg) {