DF-0745 / run.log
=== DF-0745 deterministic harness: l2cap_request_free / l2cap_rtx double-free + TAILQ-corruption race ===
transcribed from sys/netbt/l2cap_misc.c:163-197 and sys/kern/kern_timeout.c:857-930
########## SCENARIO 1: pure double-free (no slab reuse) ##########
[setup] req=0x8005008c0 on g_link=0x4036b0 (ACTIVE+armed, in hl_reqs)
[TAILQ_REMOVE] Thread B stale-remove (#2 on req): req=0x8005008c0 cached-link=0x4036b0; req->lr_link=0x0; tqe_prev=0x4036b0 tqe_next=0x0
-> stale tqe_prev dereferenced by TAILQ_REMOVE writes into whatever list the reuser put this slot on (cross-list corruption)
[zfree] DOUBLE-FREE DETECTED: req=0x8005008c0 already marked ZENTRY_FREE -> would zerror(ZONE_ERROR_ALREADYFREE) -> panic("zone: freeing free entry") on GENERIC
zone_free() calls on req slot: 2 (expected 2)
double-free events: 1
stale TAILQ_REMOVE events: 1
>>> DOUBLE-FREE CONFIRMED (vm/vm_zone.c:235 ZONE_ERROR_ALREADYFREE -> panic on GENERIC) <<<
########## SCENARIO 2: slab reuse between the two frees ##########
[setup] req=0x800500880 on g_link=0x4036b0 (ACTIVE+armed, in hl_reqs)
[reclaim] slab reuse: zone_alloc returned 0x800500880 (== old req slot); now a live request on g_link2.hl_reqs (pre-callout-arm window)
[TAILQ_REMOVE] Thread B stale-remove (#2 on req): req=0x800500880 cached-link=0x4036b0; req->lr_link=0x403690; tqe_prev=0x403690 tqe_next=0x0
-> stale tqe_prev dereferenced by TAILQ_REMOVE writes into whatever list the reuser put this slot on (cross-list corruption)
zone_free() calls on req slot: 2 (expected 2)
double-free events: 0
stale TAILQ_REMOVE events: 1
g_link2.hl_reqs.tqh_first = 0x0 (reused req=0x800500880); LIVE REQ UNLINKED by Thread B's stale remove
>>> TAILQ CORRUPTION CONFIRMED (stale tqe_prev dereferenced; live req on g_link2 unlinked by Thread B's stale remove) <<<
>>> FREE-OF-LIVE-OBJECT CONFIRMED (slab reuse turned the double-free into freeing the reuser's in-use request -> use-after-free) <<<
=== SUMMARY ===
Scenario 1 (double-free): CONFIRMED
Scenario 2 (TAILQ/UAF corruption): CONFIRMED
>>> DF-0745 REPRODUCED: double-free AND TAILQ/use-after-free corruption both confirmed <<<