⬢ DragonFlyBSD Kernel Audit
DF-5548 / fix_validation.log
← back to finding ↓ download raw
# 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.