DF-2925 / verdict.json
{ "finding_id": "DF-2925", "status": "reproduced", "reproduced": 1, "impact": "leak", "confidence": "certain", "verdict": "Uninitialized kernel stack disclosed to unprivileged users through quota accounting. cmd_set_limit() (vfs_quota.c:273-284) stores the never-initialized uint64_t 'limit' into mp->mnt_acct.ac_limit when the \"limit\" key is absent (prop_dictionary_get_uint64 leaves *valp untouched on failure, prop_dictionary_util.c), and cmd_get_usage_all() echoes ac_limit to userspace (vfs_quota.c:184). Observed: consecutive unprivileged calls leaked 0x10, 0, 3, 4, 5, ... i.e. the previous syscall's leftover stack slot (the value tracks prior activity = steerable disclosure; same pattern for 'space' at :249/:263 and the locals at :293/:314). On the DF-2922-patched kernel (which zero-initializes these) the same PoC reports 0 across all runs โ fix validated on the same build.", "exploit_chain": "", "evidence": [ "run.log โ 5-run sample: leaked ac_limit=0x10/0x0/0x3/0x4/0x5 (not attacker-set, varies with prior syscall)", "run.200.log โ 200-run sweep showing the slot tracks the previous call's loop counter" ], "kernel_refs": [ "sys/kern/vfs_quota.c:277", "sys/kern/vfs_quota.c:280", "sys/kern/vfs_quota.c:184", "sys/kern/vfs_quota.c:249", "sys/kern/vfs_quota.c:263", "sys/libprop/prop_dictionary_util.c" ], "poc_changes": "prop_object_is_array() is not exported to userland โ removed from the reply parser.", "attempts": 3, "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": 60, "guest_dirty": 0, "build_cmd": "cc -O -o vqleak vqleak.c -lprop", "run_cmd": "/tmp/vqleak /boot 5 (as uid 1001)", "code_hash": "46aa0f37447d67992f58aaa77796125404f363dd8fec8afaf35d745e498023c2", "notes": "Precondition: vfs.quota_enabled=1. 8 bytes of kernel stack per call; a pointer-seeding syscall run immediately before vquotactl would place kernel pointers in the slot (KASLR-defeating use on hardened builds).", "recommended_fix": "Zero-initialize limit/space/id before the prop_dictionary_get_* calls (included and validated in DF-2922's fix.diff).", "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": "On kernel #1 with the zero-initialization in fix.diff, the same PoC reports ac_limit=0 on every run (was nonzero stack garbage on #0).", "fix_evidence": "VERDICT.md in DF-2922 pack (fix validation section); run on patched kernel: all runs 0x0" } |