{
 "finding_id": "DF-3120",
 "status": "reproduced",
 "reproduced": 1,
 "impact": "panic",
 "confidence": "certain",
 "verdict": "Race double-execution of ufs_quotaoff proven on a QUOTA-enabled DragonFly 6.5-DEVELOPMENT x86_64 INVARIANTS kernel: two quotactl-capable threads passing the um_quotas[type]==NULLVP test at ufs_quota.c:503 both run the teardown. Clean baseline panicked <=45s with panic: VOP_STDCLOSE: BAD OPENCOUNT (stack vn_close<-ufs_quotaoff<-ufs_quotactl) proving the double vn_close at :519; an instrumented run of the same race trapped at crfree+0xc with fault address 0x0, the crfree(NOCRED) NULL-deref at :521 (NOCRED==(struct ucred *)0). QTF_CLOSING (:505) is never tested by quotaoff itself and vfs_busy (ufs_vfsops.c:141) is a shared pin, so nothing serializes. Both manifestations match the source analysis. Privilege gate: every path in needs caps_priv_check(SYSCAP_NOQUOTA_WR) (or unmount-side quotaoff, which vfs_busy/MNTK_UNMOUNT serializes), so this is privileged-admin kernel corruption/DoS (Medium), not an unprivileged escalation; realistic ceiling is a delegated quota-capable process turning its narrow capability into a vnode UAF. Stock X86_64_GENERIC has no options QUOTA (quotactl=EOPNOTSUPP), so a QUOTA kernel was built in-guest for verification. fix.diff (per-mount um_quota_lock; vp unlocked before lock in quotaon) was validated: identical PoC survived 300s/19M ops and a 120s confirmation with zero panics vs <=45s panic baseline.",
 "exploit_chain": "",
 "evidence": [
  "findings/poc/DF-3120/panic.txt \u2014 baseline panic: panic: VOP_STDCLOSE: BAD OPENCOUNT, stack vop_stdclose<-vop_close<-vn_close<-ufs_quotaoff<-ufs_quotactl",
  "findings/poc/DF-3120/panic.diag.txt \u2014 instrumented run: DF3120-DIAG: race window entered (in-flight=1) then Fatal trap 12 ... fault virtual address = 0x0, Stopped at crfree+0xc: cmpq $0,(%rdi)",
  "findings/poc/DF-3120/run.log \u2014 patched kernel: SURVIVED ... EXITED_RC=0 over 300s (17.8M offs) + 120s confirmation, dmesg panic count 0",
  "findings/poc/DF-3120/fix.diff \u2014 validated fix (git-apply-able, patch(1) -p1 verified byte-identical to tested kernel source)",
  "findings/poc/DF-3120/env.txt, VERDICT.md, README.md"
 ],
 "kernel_refs": [
  "sys/vfs/ufs/ufs_quota.c:503",
  "sys/vfs/ufs/ufs_quota.c:505",
  "sys/vfs/ufs/ufs_quota.c:519",
  "sys/vfs/ufs/ufs_quota.c:521",
  "sys/vfs/ufs/ufs_quota.c:522",
  "sys/vfs/ufs/ufs_quota.c:437",
  "sys/vfs/ufs/ufs_quota.c:448",
  "sys/vfs/ufs/ufs_quota.c:909",
  "sys/vfs/ufs/ufs_vfsops.c:141",
  "sys/sys/ucred.h:82",
  "sys/kern/vfs_lock.c:354"
 ],
 "poc_changes": "Fixed QCMD packing (kernel Q_* constants are pre-shifted: cmds = Q_cmd<<8 | type, e.g. 0x10000 for user-quota Q_QUOTAON \u2014 the seed sketchs semantics double-shifted correctly by accident but sanity tools used 0x100 and got EINVAL); added 8 rotating quota files and a distinct /qtmnt/ctrlN control path per thread (a shared control files namecache entry serializes the whole quotactl syscall and hides the race \u2014 with a shared path 1.5M quotactls produced zero window entries); unprivileged nobody children for Q_SYNC/Q_GETQUOTA/churn; children poll /tmp/QTSTOP (inherited flag never propagates to forked children); discovered stock kernel needs options QUOTA (X86_64_QUOTA built in-guest via make nativekernel).",
 "attempts": 4,
 "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Sun Sep 6 20:12:38 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_QUOTA x86_64 (baseline panic kernel: same tree #0 Sun Sep 6 18:19:17 UTC 2026)",
 "runtime_sec": 9600,
 "guest_dirty": 0,
 "build_cmd": "cc -O -pthread -o /root/qt_race /root/qt_race.c (guest kernels: cp X86_64_GENERIC X86_64_QUOTA + options QUOTA; make nativekernel && make installkernel KERNCONF=X86_64_QUOTA)",
 "run_cmd": "vnconfig -c /dev/vn0 /qt.img && newfs -m 0 /dev/vn0 && mount -t ufs /dev/vn0 /qtmnt && /root/qt_race 100",
 "code_hash": "1de2bc5175159a8b9366655e5e325fd9f631d208b17b064c5366ab0a9572c5b3",
 "notes": "Panic reproduced twice (two distinct manifestations: double vn_close via VOP_STDCLOSE BAD OPENCOUNT on clean baseline; crfree NULL-deref on instrumented kernel). No unprivileged trigger exists (privilege-checked entry), so no uid0 chain is possible for this bug; impact ceiling documented in VERDICT.md. Fix validation also caught and corrected a lock-order bug in my first fix iteration (vp lock held across um_quota_lock) \u2014 documented. Related-but-distinct from known DF-0847 (unlocked global dquot hash/free-list, unpriv-vs-unpriv) and DF-0846 (sequential cred/vp leak in quotaon): this finding is the mount-level quota state machine with a privileged race pair.",
 "recommended_fix": "Serialize ufs_quotaon/ufs_quotaoff with a per-mount lockmgr lock (um_quota_lock, lockinit in ffs_mountfs); wrap quotaoff body as ufs_quotaoff_locked so quotaons internal swap-call doesnt self-deadlock; unlock the quota-file vp before taking the lock.",
 "fix_status": "fixed",
 "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Sun Sep 6 20:12:38 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_QUOTA x86_64",
 "fix_baseline_reproduced": 1,
 "fix_patched_reproduced": 0,
 "fix_verdict": "Baseline panicked <=45s (VOP_STDCLOSE: BAD OPENCOUNT via ufs_quotaoff->vn_close); patched kernel survived the identical PoC for 300s (1.5M Q_QUOTAON + 17.8M Q_QUOTAOFF) plus a 120s confirmation run, exit 0, zero panics, mount healthy. Bad behavior gone.",
 "fix_evidence": [
  "findings/poc/DF-3120/panic.txt (baseline panic)",
  "findings/poc/DF-3120/run.log (patched SURVIVED, RC=0, x2 runs)",
  "findings/poc/DF-3120/fix.diff (validated, patch -p1 byte-identical to tested source)"
 ]
}