DF-2926 / verdict.json
{ "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" } |