DF-0823 / run.log
=== 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.