Browse Source

fix: defer connection_close in ready_cb using uasync_call_soon

ca_ready_cb and cc_parallel_ready_cb called etcp_connection_close
synchronously on non-selected connections from within the ready_cbk
callback chain. This corrupts senders_list in topo_group, causing
UAF in topo_group_start_link_nat_check.

Now uses uasync_call_soon (zero-delay timer) to defer the close
to the next event loop iteration, after the callback chain completes
and callbacks_running flag is reset.
topo_upd
Evgeny 3 months ago
parent
commit
9378b18ce7
  1. 4
      tools/chatgui/transport/chat_core.c

4
tools/chatgui/transport/chat_core.c

@ -727,7 +727,7 @@ static void cc_parallel_ready_cb(struct ETCP_CONN* conn, void* arg) {
for (int i = 0; i < st->addr_count; i++) {
if (st->timers[i]) { uasync_cancel_timeout(st->inst->ua, st->timers[i]); st->timers[i] = NULL; }
if (st->conns[i] && i != pctx->addr_index) { etcp_connection_close(st->conns[i]); st->conns[i] = NULL; }
if (st->conns[i] && i != pctx->addr_index) { uasync_call_soon(st->inst->ua, st->conns[i], (timeout_callback_t)etcp_connection_close); st->conns[i] = NULL; }
}
u_free(pctx);
cc_parallel_cleanup(st);
@ -957,7 +957,7 @@ static void ca_ready_cb(struct ETCP_CONN* conn, void* arg) {
CC_ID, ctx->addr_index, (unsigned long long)st->node_id);
for (int i = 0; i < st->addr_count; i++) {
if (st->timers[i]) { uasync_cancel_timeout(st->inst->ua, st->timers[i]); st->timers[i] = NULL; }
if (st->conns[i] && i != ctx->addr_index) { etcp_connection_close(st->conns[i]); st->conns[i] = NULL; }
if (st->conns[i] && i != ctx->addr_index) { uasync_call_soon(st->inst->ua, st->conns[i], (timeout_callback_t)etcp_connection_close); st->conns[i] = NULL; }
}
etcp_conn_remove_ready_cbk(conn, ca_ready_cb, ctx);
st->result_cb(CONN_MGR_OK, st->node_id, st->result_arg);

Loading…
Cancel
Save