--- id: "bug-352" status: "fixed" status_updated: "2026-09-24" status_note: "" component: "controller" severity: "crash" timestamp: "2026-06-10T01:46:28.589Z" last_seen: "2026-09-19T09:00:00Z" occurrences: 2 files: ["src/controller/ha.c"] tags: ["c", "ha", "election", "asan", "use-after-free", "packet-ownership", "netio", "e2e"] related: [] legacy: true --- # bug-352: ASAN heap-use-after-free in free_packet (netio.c:333) via endpoint_fini <- raft_cb_become_follower… ## Description ASAN heap-use-after-free in free_packet (netio.c:333) via endpoint_fini <- raft_cb_become_follower (loser path) <- raft_on_vote_reply; election loser crashes on vote-reply processing ## Environment _Not recorded (migrated from buglog.json)._ ## Reproduction _Not recorded (migrated from buglog.json)._ ## Root cause vote_reply_decode_and_dispatch took pkt = ep->fsm_in.pkt and freed it WITHOUT clearing ep->fsm_in.pkt; vote_reply_dispatch can synchronously reach raft_cb_become_follower -> endpoint_fini(ep), which frees the stale fsm_in.pkt again. repl_ack_decode_and_dispatch already nulls the pointer (correct pattern); the vote-reply path missed it. ## Fix FIXED 2026-06-10: ep->fsm_in.pkt = NULL immediately after taking ownership in vote_reply_decode_and_dispatch (ha.c:2413), matching repl_ack_decode_and_dispatch. Found by task 7.7 E2E (3-node deploy, election loser crash). ## Verification _Not recorded (migrated from buglog.json)._ ## References _Not recorded (migrated from buglog.json)._