DF-5686 / verdict.json
{ "finding_id": "DF-5686", "status": "reproduced", "reproduced": true, "impact": "leak", "confidence": "certain", "verdict": "REPRODUCED: udev_getdevs_ioctl() never releases ctx.cdevs after prop_dictionary_set(odict, \"array\", ctx.cdevs) (set retains; the callers own reference leaks). 500 UDEVPROP getdevs ioctls as root -> +490 prop_array/proparay InUse, +625KB live kernel heap (~1.3KB per ioctl), plus one permanent reference on every cdev si_dict per call (pins device dicts past device destruction). Direct trigger is root-gated (/dev/udev 0600) but devd(8) performs the same ioctl on default systems (idle drift proparay 1->9 observed over ~10min). fix.diff (one-line prop_object_release(ctx.cdevs)) validated on rebuilt kernel: 500 ioctls -> counters flat.", "exploit_chain": "", "evidence": "run.log (proparay 1.97K->2.46K InUse, prop_array +625KB per 500 ioctls), run.patched.log (flat after fix)", "kernel_refs": [ "sys/kern/kern_udev.c:985", "sys/kern/kern_udev.c:1004", "sys/kern/kern_udev.c:1013", "sys/kern/kern_udev.c:1039", "sys/libprop/prop_kern.c:585" ], "poc_changes": "Hand-crafted proplib XML (<plist><dict><key>command</key><string>getdevs</string></dict></plist>) since guest lacks userland proplib headers; plistref + UDEVPROP _IOWR defined locally; munmap of the kernel copyout region added per _prop_object_copyout contract.", "attempts": 1, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64 (baseline) / #1: Sat Oct 10 00:36:54 UTC 2026 (patched)", "runtime_sec": 120, "guest_dirty": 0, "build_cmd": "cc -O2 -o udev_getdevs_leak udev_getdevs_leak.c", "run_cmd": "as root: ./udev_getdevs_leak /dev/udev 500 ; vmstat -m | grep -i prop", "code_hash": "968092fb5abff4e934860b2dbd8b079312747c5872d60bdb6409081b3788ef00", "notes": "Guest reset (vm.sh reset with-src) performed after the run; evidence captured on baseline kernel #0 and patched kernel #1.", "recommended_fix": "Add prop_object_release(ctx.cdevs) after prop_dictionary_copyout_ioctl", "fix_status": "fixed", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "Patched kernel #1 with prop_object_release(ctx.cdevs): 500 getdevs ioctls leave prop_array InUse at 0 and proparay flat. Leak eliminated, getdevs output path unchanged.", "fix_evidence": "run.patched.log", "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Sat Oct 10 00:36:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64" } |