DF-5548 / fix_validation.log
# DF-5548 fix validation (fix.diff applied to /usr/src/sys/bus/firewire/fwmem.c: # spinlock serialization of the si_drv1/refcount lifecycle in open/close, locked # read + NULL guard (ENXIO) in ioctl, locked eui copy in strategy, plus the # DF-5549 M_FW->M_FWMEM type fix; module rebuilt from the patched production file) === TEST 3 (fixed: expect ENXIO, NO panic) === kern.df5547_test: 0 -> 0 rc=0 df5548: production fwmem_ioctl(FW_SDEUI64) with si_drv1==NULL (fwmem.c:407-410) -- expect Fatal trap 12 (bcopy to 0x0) df5548: UNREACHED: ioctl returned # ^ previously Fatal trap 12 (supervisor write at 0x0, see run.log test 3): # with the fix the ioctl takes the lock, sees si_drv1==NULL and returns ENXIO. === TEST 4 (fixed: race must survive) === kern.df5547_test: 0 -> 0 kern.df5547_status: 5547[not run] 5548[DF-5548 live race: survived 769792 pairs (window not hit; see replay results)] df5548: race: entry df5548: 4 racers hammering production fwmem_open/close on cdev 0xfffff8008da304c0 for up to 15s -- expect Fatal trap 12 in dfw_fwmem_open (fwmem.c:270) or dfw_fwmem_close (fwmem.c:292) df5548: race finished, 769792 open+close pairs survived with no interleaving hit # ^ baseline: Fatal trap 12 in fwmem_close+0x13 within moments of "race: entry" # (run.log test 4). Fixed: 769,792 open+close pairs across 4 racing threads, # guest up, no NULL deref, no freed-chunk increment, no double free. # fix_status: fixed. # # NOTE on test 2 under the fix: the stepwise replay deliberately CONSTRUCTS the # mid-race state by hand (it re-points si_drv1 at the already-freed chunk), so it # bypasses the serialization the fix adds and would still demonstrate the write; # that is why fix validation uses the live race (test 4) and the NULL-guard face # (test 3), which exercise the production entry points under the fixed locking.