forked from lei.chen/myxce
Raft-drive-async's reconnect-offload burst (Task 2.1/2.2) exposed a latent race in io_worker's epoll dispatch loop: ha.c's on_standby_connected() evicts a stale duplicate peer channel via iomgr_unmonitor()+endpoint_unref(), but epoll_ctl(DEL) only stops FUTURE epoll_wait() calls -- it does not invalidate an event for that same endpoint already sitting in the CURRENT batch's events[] array. A later event in the same batch then dereferences the freed endpoint_t/SSL*, producing the ASAN SEGV observed deep inside OpenSSL's ssl3_read_bytes during raft-drive-async's round-9 soak. The original "concurrent SSL_do_handshake from two io_worker threads" hypothesis was wrong and is retracted -- iomgr_start() creates exactly one io_worker thread per iomgr_t. Fix: extract io_worker_dispatch_batch(), which takes endpoint_ref() on every endpoint in the batch before dispatching any of them and endpoint_unref()s each only after the whole batch completes -- the same lock-free ref/unref bracket already used for bug-1298 and INVOKE_MSG_HANDLER, just never applied to io_worker's own loop. Pure atomics, no locks, no blocking added to the hot path. Adds test_netio_batch_dispatch_uaf.c, which drives the real dispatch loop with a synthetic epoll_event[] batch (TDD RED confirmed via ASAN heap-use-after-free before the fix, GREEN after). Verified further with two independent clean 10-round live sequential HA soaks (33 and 36 jobs, zero loss) and full ASAN suite runs (xcelib_test 294/0, controller_unit_test 972/0). raft-drive-async's kiro-validate-impl re-run flips NO-GO to GO. |
||
|---|---|---|
| .. | ||
| admin-config-tool | ||
| config-upgrade-snapshot | ||
| controller-status | ||
| election-iomgr-refactor | ||
| ha-commit-barrier-rollout | ||
| ha-commit-durability | ||
| ha-commit-engine | ||
| ha-config-bootstrap | ||
| ha-consistency-invariants | ||
| ha-convergence-recovery | ||
| ha-elect-ctx-lifecycle | ||
| ha-entity-snapshots | ||
| ha-heartbeat-committed-propagation | ||
| ha-heartbeat-liveness | ||
| ha-peer-connection-reuse | ||
| ha-prevote | ||
| ha-repl-hardening | ||
| ha-single-leader-role | ||
| ha-term-safety | ||
| ha-wal-replication | ||
| job-array-single-wal-record | ||
| libxce-failover | ||
| raft-apply-decoupling | ||
| raft-commit-safety | ||
| raft-drive-async | ||
| raft-ha-core-safety | ||
| raft-library | ||
| raft-log-replication | ||
| raft-sim-conformance | ||
| resval-id-decoupling | ||
| scheduler-controller-msg-gap | ||
| scheduler-framework | ||
| worker-join-refactor | ||
| xce-test-e2e-primitives | ||
| .gitignore | ||