Browse Source

route_connectivity: fix UAF in conn_probe_finish — break ctx->nq on cancel_node, always free ctx in finish

chatgui
Evgeny 3 months ago
parent
commit
aa73e9d8cb
  1. 1
      src/control_server.c
  2. 11
      src/route_connectivity.c
  3. 1
      src/route_node.h

1
src/control_server.c

@ -91,6 +91,7 @@ static void client_write_callback(socket_t fd, void* arg);
static void client_except_callback(socket_t fd, void* arg); static void client_except_callback(socket_t fd, void* arg);
static void handle_client_data(struct control_server* server, struct control_client* client); static void handle_client_data(struct control_server* server, struct control_client* client);
static void close_client(struct control_server* server, struct control_client* client); static void close_client(struct control_server* server, struct control_client* client);
static void control_client_idle_cb(void* arg);
static void send_conn_list(struct control_server* server, struct control_client* client, uint8_t seq_id); static void send_conn_list(struct control_server* server, struct control_client* client, uint8_t seq_id);
static void send_socket_list(struct control_server* server, struct control_client* client, uint8_t seq_id); static void send_socket_list(struct control_server* server, struct control_client* client, uint8_t seq_id);

11
src/route_connectivity.c

@ -245,8 +245,10 @@ static void conn_probe_single_cb(int success, uint16_t rtt, void* arg,
} }
static void conn_probe_finish(struct conn_probe_ctx* ctx, int ok) { static void conn_probe_finish(struct conn_probe_ctx* ctx, int ok) {
if (!ctx || !ctx->nq) return; if (!ctx) return;
if (ctx->nq) {
struct NODE_CONNECTIVITY* c = &ctx->nq->connectivity; struct NODE_CONNECTIVITY* c = &ctx->nq->connectivity;
if (c->probe_ctx == ctx) c->probe_ctx = NULL;
switch (ctx->addr_type) { switch (ctx->addr_type) {
case ADDR_TYPE_INTERFACE: case ADDR_TYPE_INTERFACE:
@ -273,6 +275,7 @@ static void conn_probe_finish(struct conn_probe_ctx* ctx, int ok) {
(unsigned long long)ctx->nq->node.node_id, (unsigned long long)ctx->nq->node.node_id,
c->interface_status, c->nat_status, c->real_status); c->interface_status, c->nat_status, c->real_status);
} }
}
u_free(ctx); u_free(ctx);
} }
@ -349,6 +352,7 @@ void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct NODEIN
ctx->timeout_ms = CONN_PROBE_TIMEOUT_MS; ctx->timeout_ms = CONN_PROBE_TIMEOUT_MS;
ctx->best_across_sockets = 65535; ctx->best_across_sockets = 65535;
nq->connectivity.probe_ctx = ctx;
pend++; pend++;
conn_probe_start_series(ctx); conn_probe_start_series(ctx);
} }
@ -407,6 +411,7 @@ void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct NODEIN
ctx->timeout_ms = CONN_PROBE_TIMEOUT_MS; ctx->timeout_ms = CONN_PROBE_TIMEOUT_MS;
ctx->best_across_sockets = 65535; ctx->best_across_sockets = 65535;
nq->connectivity.probe_ctx = ctx;
pend++; pend++;
conn_probe_start_series(ctx); conn_probe_start_series(ctx);
} }
@ -428,6 +433,10 @@ void route_connectivity_cancel_node(struct UTUN_INSTANCE* instance, struct NODEI
if (!instance || !nq) return; if (!instance || !nq) return;
nq->connectivity.probe_status = PROBE_STATUS_NONE; nq->connectivity.probe_status = PROBE_STATUS_NONE;
nq->connectivity.pending_count = 0; nq->connectivity.pending_count = 0;
if (nq->connectivity.probe_ctx) {
((struct conn_probe_ctx*)nq->connectivity.probe_ctx)->nq = NULL;
nq->connectivity.probe_ctx = NULL;
}
DEBUG_INFO(DEBUG_CATEGORY_BGP, "connectivity probe cancelled for node %016llx", (unsigned long long)nq->node.node_id); DEBUG_INFO(DEBUG_CATEGORY_BGP, "connectivity probe cancelled for node %016llx", (unsigned long long)nq->node.node_id);
} }

1
src/route_node.h

@ -56,6 +56,7 @@ struct NODE_CONNECTIVITY {
uint64_t nat_probe_time; uint64_t nat_probe_time;
uint64_t real_probe_time; uint64_t real_probe_time;
uint64_t ping_req_time; // время последнего полученного ping request от этого узла (0.1ms tb) uint64_t ping_req_time; // время последнего полученного ping request от этого узла (0.1ms tb)
void* probe_ctx; // активный conn_probe_ctx (для cancel)
}; };
/** /**

Loading…
Cancel
Save