=== DF-0823 trigger run on unpatched baseline === Kernel: DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 Command: /root/trigger.sh (as root) [*] Creating hammer2 images... 268435456 bytes transferred in 0.388305 secs (691300949 bytes/sec) 268435456 bytes transferred in 0.375797 secs (714310021 bytes/sec) [*] newfs_hammer2 both devices... fsid 82cb8416-78f1-11f1-8392-010000000000 fsid 82cddd47-78f1-11f1-8392-010000000000 [*] Creating MASTER PFS 'testpfs' on /dev/vn0... hammer2: pfs_create(testpfs): SUCCESS [*] MASTER PFS mounted at /mnt/test [*] MASTER clid: 82dddd1f-78f1-11f1-8392-010000000000 [*] Creating SLAVE PFS 'testpfs' on /dev/vn1 with matching clid... hammer2: pfs_create(testpfs): SUCCESS [*] Device B PFS list: [*] Triggering I/O to spin up XOP threads... [*] Unmounting device B @DATA (SLAVE chain stays in PMP)... [*] Unmounting cluster PFS (triggers cleanup loop mismatch)... [*] BUG: cleanup stops thread[0] only, kfree's xop_groups, thread[1] orphaned [!] Umount complete. Waiting for orphan thread to access freed heap... [!] On BUGGY kernel: expect fatal trap 12 page fault within ~10s. <<< SSH CONNECTION LOST — kernel panicked >>> === Serial console (dfbsd-qemu/boot.log) — kernel trace preceding panic === hammer2_mount: devstr="/dev/vn0@DATA" hammer2_mount: hmp=0xfffff80118460000 pmp=0xfffff80118c40000 ADD LOCAL PFS (IOCTL): testpfs ← MASTER testpfs created on vn0 hammer2_mount: devstr="/dev/vn0@testpfs" hammer2_mount: hmp=0xfffff80118460000 matched hammer2_mount: hmp=0xfffff80118460000 pmp=0xfffff801197e4000 ← testpfs PMP (nchains=1) hammer2_mount: devstr="/dev/vn1@DATA" hammer2_mount: hmp=0xfffff80119dac000 pmp=0xfffff8011a540000 ADD LOCAL PFS (IOCTL): testpfs ← SLAVE testpfs found → added to PMP (nchains=2) <<< umount /mnt/h2b (vn1@DATA) — mount_count > 0, pfsfree_scan skipped >>> <<< umount /mnt/test (vn0@testpfs) — hammer2_xop_helper_cleanup: stops thread[0] only, kfree(xop_groups) frees backing memory. Orphan thread[1] (SLAVE) running on freed heap. >>> Fatal trap 12: page fault while in kernel mode cpuid = 1; lapic id = 1 fault virtual address = 0xfffff8011a1d5558 fault code = supervisor write data, page not present instruction pointer = 0x8:0xffffffff8095da89 current process = Idle current thread = pri 12 (CRIT) Stopped at hammer2_primary_xops_thread+0x2d9: lock xaddl %edx,0x81558(%rsi) db> === Analysis === The faulting instruction `lock xaddl %edx,0x81558(%rsi)` is an atomic add within hammer2_primary_xops_thread. %rsi points to the PMP base (0xfffff8011a154000 in the first run), and 0x81558 is the offset to the orphaned thread[1]'s fields within the freed xop_groups slab. The page at that address was freed by kfree(xop_groups) and unmapped, causing the page-not-present fault. This is a textbook use-after-free: the cleanup loop at hammer2_admin.c:461 iterates pfs_nmasters (count of MASTER chains only = 1) while the create loop at :437 iterates cluster.nchains (= 2). The SLAVE-indexed thread[1] is never stopped before kfree(xop_groups) at :468 frees its backing memory.