DF-4879 / verdict.json
{ "finding_id": "DF-4879", "status": "untested", "reproduced": 0, "impact": "none", "confidence": "likely", "verdict": "Source-proven defect, not runnable on the audit guest: drm_mode_config_init() (sys/dev/drm/drm_mode_config.c:392) ignores the -ENOMEM return of drm_mode_create_standard_properties() (lines 217-353), leaving later standard properties NULL; drm_universal_plane_init()/drm_crtc_init_with_planes() attach those NULL pointers to every plane/CRTC (drm_plane.c:262-275, drm_crtc.c:339-341), and the unauthenticated DRM_IOCTL_MODE_OBJ_GETPROPERTIES (drm_ioctl.c:678, DRM_UNLOCKED|DRM_RENDER_ALLOW) dereferences prop->flags (drm_mode_object.c:345) -> kernel NULL-deref panic. Precondition is allocation failure during privileged driver load (i915/radeon/amdgpu all treat init as infallible: intel_display.c:15342, radeon_display.c:1579, amdgpu_device.c:2604); the trigger itself is an unprivileged ioctl. Guest has no /dev/dri (no GPU) and no memory-fault-injection knob, so no live PoC was possible. Derefs are read-only: no write primitive, no kernel disclosure; impact ceiling is local DoS (panic). Upstream-inherited (Linux ~4.19 void drm_mode_config_init); upstream later fixed the class via drmm_mode_config_init() which fails device init.", "exploit_chain": "", "evidence": "VERDICT.md carries the full path:line chain (init:392 -> attaches: drm_plane.c:262-275/drm_crtc.c:339-341 -> sink: drm_mode_object.c:345 via drm_ioctl.c:678). trigger.c is the reference prober (count_props=64 forces the prop->flags read). Guest live-check: /dev/dri absent (documented in VERDICT.md).", "kernel_refs": [ "sys/dev/drm/drm_mode_config.c:392", "sys/dev/drm/drm_mode_config.c:217", "sys/dev/drm/drm_mode_config.c:221", "sys/dev/drm/drm_plane.c:262", "sys/dev/drm/drm_plane.c:267", "sys/dev/drm/drm_crtc.c:339", "sys/dev/drm/drm_mode_object.c:341", "sys/dev/drm/drm_mode_object.c:345", "sys/dev/drm/drm_ioctl.c:678", "sys/dev/drm/i915/intel_display.c:15342", "sys/dev/drm/radeon/radeon_display.c:1579", "sys/dev/drm/amd/amdgpu/amdgpu_device.c:2604" ], "poc_changes": "no seed PoC existed; trigger.c written from scratch as a reference prober, never executed (no DRM device on guest)", "attempts": 0, "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": 15, "guest_dirty": 0, "build_cmd": "cc -O2 -o df4879 trigger.c (reference only; not executed on the audit guest)", "run_cmd": "./df4879 /dev/dri/card0 (reference only: no /dev/dri on the audit guest)", "code_hash": "c7b439a0d355c98760df4f135e05299fc9e8789a8c24598934744cd44b57c615", "notes": "Pass 2 (GLM 5.3) of drm_mode_config.c; pass 1 was clean. Live checks this run: /dev/dri absent on guest; nvmm.ko loads but MOD_LOAD fails cpu not supported (no SVM/VMX under QEMU) so /dev/nvmm cannot exist here; when attachable the node is root:nvmm 0640 (nvmm_dragonfly.c:392). Low severity: trigger unprivileged, but vulnerable state requires privileged load under ENOMEM; read-only derefs cap impact at panic/DoS.", "recommended_fix": "Make drm_mode_config_init() return int, propagate drm_mode_create_standard_properties() failure, and abort driver load at the three call sites (fix.diff mirrors upstreams drmm_mode_config_init semantics)", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "Cannot build a DRM-bearing kernel config on this guest (no GPU to bind; also cannot force the ENOMEM precondition), so baseline-vs-patched comparison is not testable here. The fix is the exact semantic upstream adopted (drmm_mode_config_init fails device init when standard property creation fails).", "fix_evidence": "fix.diff (git-apply-able, never applied to the read-only sys/ tree): signature change + ret propagation in drm_mode_config.c:370-401, prototype in include/drm/drm_mode_config.h:870, abort-load at intel_display.c:15342, radeon_display.c:1579, amdgpu_device.c:2604" } |