โฌข DragonFlyBSD Kernel Audit
DF-2926 / verdict.json
โ† back to finding โ†“ download raw
{
  "finding_id": "DF-2926",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "Unprivileged guaranteed kernel panic via unbounded plist allocation plus sys_vquotactl's unconditional per-call leak (DF-0146 family). sys_vquotactl() internalizes an arbitrarily large user plist and never releases it (input dict, cmd cstring, output array), so sustained unprivileged vquotactl traffic grows M_PROP_DICT/M_PROP_ARRAY monotonically until the malloc type hits ks_limit, at which point _kmalloc_obj() panics by design (kern_kmalloc.c:702-707) because proplib allocates with M_WAITOK (no M_NULLOK). Observed twice organically from uid 1001 loops (writer side AND, decisively, the 'get usage all' output path at sys_vquotactl+0x40d -> prop_dictionary_set_uint32), both with full console traces. Turned into a minimal trigger (vqalloc.c). Not a re-report of DF-0146: the new result is the guaranteed unprivileged panic from the leak x unbounded input x panic-on-limit policy (multi-call interaction).",
  "exploit_chain": "",
  "evidence": [
    "panic.1.txt โ€” input path: _prop_dictionary_internalize_continue -> prop_dictionary_set -> _prop_dictionary_expand -> _kmalloc panic",
    "panic.2.txt โ€” OUTPUT path: sys_vquotactl+0x40d -> prop_dictionary_set_uint32 -> prop_dictionary_set -> _prop_dictionary_expand -> _kmalloc panic"
  ],
  "kernel_refs": [
    "sys/kern/vfs_quota.c:345",
    "sys/kern/vfs_quota.c:346",
    "sys/kern/vfs_quota.c:362",
    "sys/kern/vfs_quota.c:405",
    "sys/kern/vfs_quota.c:191-197",
    "sys/kern/kern_kmalloc.c:702-707"
  ],
  "poc_changes": "Trigger distilled from the organic vqlivelock writer into a standalone vqalloc.c (not executed standalone โ€” both captures are organic reproductions from equivalent loops).",
  "attempts": 2,
  "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": 120,
  "guest_dirty": 0,
  "build_cmd": "cc -O -o vqalloc vqalloc.c -lprop",
  "run_cmd": "./vqalloc /boot 128   (as uid 1001; panics within ~1 min of sustained calls)",
  "code_hash": "b788a92558830d6d85d7a58d9b5bdca93b567cc2f144615690edfae8e2ed8cb7",
  "notes": "Precondition: vfs.quota_enabled=1. This panic is INDEPENDENT of the DF-2922 fix (the leak is in sys_vquotactl's own paths) โ€” the DF-2922-patched kernel is expected to remain vulnerable here; fixing requires the DF-0146 leak fix plus an input-size bound.",
  "recommended_fix": "Release every prop object on every sys_vquotactl path; bound the accepted plist size; harden proplib internalization with M_NULLOK + ENOMEM instead of relying on panic-on-limit.",
  "fix_status": "not_testable",
  "fix_kernel_uname": "",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "not_testable: the validated single-fix kernel addresses DF-2922 only; this finding's fix (leak release + size bound) was not built within the run budget.",
  "fix_evidence": "panic.1.txt, panic.2.txt"
}