{
  "finding_id": "DF-2922",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "Unauthenticated-local (uid 1001) type confusion in sys_vquotactl: the user-controlled \"arguments\" proplib object is passed unvalidated to prop_array_iterator() (vfs_quota.c:242), which mtx_lock()s the object at the _prop_array.pa_rwlock offset BEFORE type-checking it (prop_array.c:538-546). On the stock INVARIANTS kernel the aliased 40-byte struct mtx over non-array memory produces: <false/> -> Fatal trap 12 page fault in the mutex sleep path (strncpy of the aliased mtx_ident as tsleep wchan) with ac_spin held ('panic with 1 spinlocks held'), deterministic 3/3 fresh boots; <true/> -> Fatal trap 9 GPF at the exlink-enqueue store movq %r12,(%rax) (writes a kernel stack pointer through the aliased pointer, i.e. a demonstrated corruption write primitive); <integer> -> Fatal trap 9 GPF on the exlink read (aliased prop_number rb_node); <string> -> silent full-system kernel livelock (QEMU pinned 102% CPU, OS dead, no console output) because the aliased lock word is a heap pointer that never clears. Dict control returns cleanly. A crash dump was captured and the auto-backtrace confirms the _mtx_lock_ex -> mtx_wait_link -> strncpy chain. Full uid=0 chain (grooming the string/number pools so the aliased exlink aims the stack-pointer write at a controlled address) was not completed; the corruption primitive itself is proven. Fix validated: with type checks added in vfs_quota.c, the same single-fix kernel survives all four knockdown variants (20/20 clean returns) and the guest stays up.",
  "exploit_chain": "unpriv vquotactl(\"set usage all\", arguments=<non-array proplib object>) -> prop_dictionary_copyin internalizes the attacker plist -> cmd_set_usage_all (holds mount ac_spin) -> prop_array_iterator -> mtx_lock on aliased fields of attacker-typed object -> __mtx_lock_ex slowpath writes MTX_EXWANTED|MTX_LINKSPIN into aliased word, stores/reads kernel stack pointers via mtx_exlink -> fatal trap (12/9) or infinite kernel spin with ac_spin held. Escalation potential (not completed): shape the aliased bytes via a prop_string so the exlink-derived write lands on a pooled object's refcount/type.",
  "evidence": [
    "panic.false.txt — Fatal trap 12, fault va 0x40, strncpy+0x1f, 'panic with 1 spinlocks held', 3/3 fresh boots",
    "panic.dump.txt — crash-dump auto-backtrace: strncpy <- _mtx_lock_ex+0x130 (return addr of callq mtx_wait_link)",
    "panic.true.txt — Fatal trap 9 at _mtx_lock_ex+0xdc movq %r12,(%rax) (write through aliased ptr)",
    "panic.number.txt — Fatal trap 9 at _mtx_lock_ex+0xc4 movq 0x8(%rax),%rcx (read side)",
    "livelock-string.txt — string variant: QEMU 102% CPU, OS dead, zero console output",
    "bss-layout.txt — nm proof of _prop_bool_false@0xffffffff8179b300 / _prop_bool_true@0x...b320 / _prop_data_pool@0x...b338 overlaid by the aliased mtx",
    "build.log + VERDICT.md — patched kernel #1 (fix.diff, -Werror clean): all variants return cleanly, 20/20, guest up"
  ],
  "kernel_refs": [
    "sys/kern/vfs_quota.c:228",
    "sys/kern/vfs_quota.c:242",
    "sys/kern/vfs_quota.c:385",
    "sys/libprop/prop_array.c:513-546",
    "sys/libprop/prop_object_impl.h:295-299",
    "sys/sys/mutex.h:66",
    "sys/kern/kern_mutex.c:85-200"
  ],
  "poc_changes": "Replaced prop_bool_false()/prop_bool_true() (not the userland API) with prop_bool_create(false/true); removed prop_object_is_array() from the userland leak helper; everything else as seeded.",
  "attempts": 7,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026     root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "runtime_sec": 3600,
  "guest_dirty": 0,
  "build_cmd": "cc -O -o typeconfuse typeconfuse.c -lprop",
  "run_cmd": "/tmp/typeconfuse /boot false|true|number|string|dict   (as uid 1001, vfs.quota_enabled=1)",
  "code_hash": "7e591a726cbd4006de7aea22b494706ac1440aa58827a50c7eecf4fb6f863b9b",
  "notes": "Guest preconditions: vfs.quota_enabled=1 boot tunable (added to /boot/loader.conf). Crash dump in guest /var/crash/vmcore.0 (DFly minidump). Severity High rather than Critical only because the completed chain is panic/corruption rather than a demonstrated uid=0; the exlink write is a genuine pointer-mediated write primitive.",
  "recommended_fix": "Validate prop_object_type(args)==PROP_TYPE_ARRAY before prop_array_iterator() and PROP_TYPE_DICTIONARY for the set-limit commands and each array element (see validated fix.diff); harden prop_array_iterator() itself to type-check before locking.",
  "fix_status": "fixed",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Thu Sep  3 13:57:47 UTC 2026     root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Single-fix kernel (fix.diff on vfs_quota.c, make nativekernel/installkernel, -Werror clean): baseline knockdowns re-confirmed fatal on #0 immediately prior; on #1 all four variants (false/true/number/string) plus dict control return cleanly, 20/20 repeat of the false variant, guest stays up throughout. Previously-observed bad behavior GONE.",
  "fix_evidence": "build.log (vfs_quota.o compiled with -Werror, RC=0, install completed); VERDICT.md fix-validation section"
}
