DF-4373 / verdict.json
{ "finding_id": "DF-4373", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "Divide-by-zero at sys/dev/drm/amd/display/dc/dce/dce_transform.c:710 (max_pixels_supports / pixel_width) guarded only by an ASSERT that compiles to WARN_ON (os_types.h:48). Reachable end-to-end from an unprivileged DRM-master session user with a UABI-legal atomic plane state: amdgpu_dm never clips plane rects to the CRTC (fill_rects_from_plane_state, amdgpu_dm.c:2210-2238) and dc_validate_plane checks format only (dc_resource.c:2891); a plane positioned flush off the right edge of the stream dst window makes calculate_recouts clamp yield recout.width == 0 exactly (dc_resource.c:639-643) while calculate_viewport keeps viewport.width >= 16 in source pixels (dc_resource.c:543), so the >=16 guard at dc_resource.c:1122 passes; prescaler_on is hard-coded true (dce_transform.c:1359) so pixel_width takes the 0 recout width and the integer division faults (#DE panic). Could not be executed on the audit QEMU guest because it has no AMD GPU (QEMU std VGA 0x1234:1111, no /dev/dri, no 0x1002 PCI device) \u2014 probe built and run on the guest, device absent. Same class as the DF-3828/DF-3857/DF-3869 DCE divide family. Local DoS (kernel panic) on real DCE100/110/112/120 hardware.", "exploit_chain": "session user (DRM master) -> atomic TEST_ONLY commit, plane src 640x480, dst CRTC_X=640/CRTC_W=1 on a 640x480 CRTC -> amdgpu_dm_atomic_check -> dc_validate_global -> resource_build_scaling -> dce_transform_get_optimal_number_of_taps -> dce_transform_get_max_num_of_supported_lines -> integer divide by zero -> kernel panic (DoS). No memory-corruption primitive; impact ceiling is denial of service.", "evidence": "VERDICT.md (full cited chain, 7 steps); run.log (guest probe: /dev/dri absent, NO_AMD_PCI); build.log (cc 8.3 BUILD_OK); fix.diff (git-apply-able guard, applies clean); README.md (underscan variant + trigger recipe)", "kernel_refs": [ "sys/dev/drm/amd/display/dc/dce/dce_transform.c:710", "sys/dev/drm/amd/display/dc/dce/dce_transform.c:675", "sys/dev/drm/amd/display/dc/dce/dce_transform.c:896", "sys/dev/drm/amd/display/dc/dce/dce_transform.c:1359", "sys/dev/drm/amd/display/dc/core/dc_resource.c:637", "sys/dev/drm/amd/display/dc/core/dc_resource.c:1122", "sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm.c:2210", "sys/dev/drm/amd/display/dc/os_types.h:48" ], "poc_changes": "Seed sketch reduced to a standalone raw-ioctl probe (no libdrm on guest); full libdrm atomic trigger recipe documented in README.md/VERDICT.md since the guest lacks the required AMD GPU.", "attempts": 1, "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": 90, "guest_dirty": 0, "build_cmd": "cc -O2 -Wall -o /tmp/trig4373 /tmp/df4373/t.c (on guest, DFly cc 8.3)", "run_cmd": "/tmp/trig4373 /dev/dri/card0 (on guest)", "code_hash": "bfe22719f456564c06d616b14bc009985afa1fbfe0654f38befa1413ded0ee71", "notes": "Target device class absent on audit guest (no AMD GPU) \u2014 per status mapping this is not_reproduced with no observed impact; the static proof chain is complete and every link is cited. Div-happens-on-the-atomic-CHECK-path, so DRM_MODE_ATOMIC_TEST_ONLY suffices on real hardware. Program could be validated only on DCE hardware; consider reporting upstream to drm/amdgpu.", "recommended_fix": "Guard the division in dce_transform_get_max_num_of_supported_lines: return 0 (no lines supported) when pixels_per_entries==0 or pixel_width<=0 so validation fails cleanly.", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff authored and git-apply-able against the read-only tree (verified with git apply --check); cannot build/boot a DCE kernel on the QEMU guest (no AMD GPU), so patched behavior could not be exercised. The guard makes get_optimal_number_of_taps return false for degenerate recout, failing atomic validation with EINVAL instead of panicking.", "fix_evidence": "fix.diff; VERDICT.md Fix validation section" } |