--- id: "bug-1482" status: "fixed" status_updated: "2026-09-24" status_note: "" component: "controller" severity: "crash" timestamp: "2026-07-29T10:43:00Z" last_seen: "2026-09-19T09:00:00Z" occurrences: 1 files: ["src/controller/testsuite/test_config_repl.c; doc comment in src/controller/cluster.c (myreq_handler_for_test)"] tags: ["cluster.c", "myreq_handler_for_test", "xce_decode", "free_packet", "use-after-free", "double-free", "misleading-doc-comment", "ownership-contract", "raft-adapter-conformance", "task-2.2", "review-finding-corrected"] related: [] legacy: true --- # bug-1482: AddressSanitizer: heap-use-after-free in free_packet ../lib/netio.c:437, called from… ## Description AddressSanitizer: heap-use-after-free in free_packet ../lib/netio.c:437, called from test_config_push_reply_higher_term_adopts_and_steps_down (test_config_repl.c:3718) ## Environment _Not recorded (migrated from buglog.json)._ ## Reproduction _Not recorded (migrated from buglog.json)._ ## Root cause A code-review finding (task 2.2 re-review) reported that cpr22_build_config_push_reply_pkt's io_packet_t* pkt was never freed after myreq_handler_for_test(...), citing myreq_handler_for_test's own doc comment ('the caller still owns/frees pkt itself') as the ownership contract. That doc comment was WRONG: myreq_handler unconditionally calls xce_decode(pkt, &request) as its first step, and xce_decode() itself (src/lib/request.c:274-275) unconditionally calls free_packet(pkt) (frees pkt->data) then FREEUP(pkt) (frees the io_packet_t struct) before returning -- ownership of pkt is transferred into xce_decode, not retained by the caller. Applying the review finding literally (adding free_packet(pkt); free(pkt); after the call) was therefore a double-free/use-after-free, caught immediately by ASAN even under ASAN_OPTIONS=detect_leaks=0 (UAF detection is independent of leak detection). ## Fix Removed the erroneous free_packet(pkt)+free(pkt) call from the test (there is no leak -- pkt is already fully consumed). Corrected myreq_handler_for_test's doc comment in cluster.c to accurately state that pkt ownership is transferred into the call via xce_decode, and callers must not touch/free pkt afterward. Added an explanatory NOTE comment at the call site in the test to prevent recurrence. ## Verification _Not recorded (migrated from buglog.json)._ ## References _Not recorded (migrated from buglog.json)._