DF-3854 / verdict.json
{ "finding_id": "DF-3854", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "Source-certain NULL dereference by check order: radeon_combios_external_tmds_setup() IGP branch executes rev = RBIOS8(offset) BEFORE testing if (offset) (radeon_combios.c:2889-2891). combios_get_table_offset() returns 0 when rdev->bios == NULL (radeon_combios.c:131) and r100_init() deliberately continues after radeon_get_bios() failure on pre-AVIVO chips (r100.c:4056-4059), so bios==NULL is a live state on exactly the RS100-RS480 IGP boards this branch serves; RBIOS8(0) then reads rdev->bios[0] with bios==NULL -> kernel page fault at address 0 -> panic at the first external-TMDS modeset (radeon_legacy_encoders.c:985). Harness replicates the deref order and dies with SIGSEGV (run.log: Segmentation fault (core dumped), exit 139). Kernel-side panic not observable on the virtio-only audit guest (0 radeon devices). Precondition chain keeps severity Low: IGP board + unreadable ROM + ext-TMDS encoder (forced connector table via root module param, or PPC Mac auto-table). The dead read is present verbatim upstream (Linux v5.10:2900) - inherited, not a port regression.", "exploit_chain": "root sets radeon.connector_table to an external-TMDS table (or PPC Mac auto-detect) on an IGP board whose ROM read failed -> driver loads with bios==NULL (pre-AVIVO does not abort) -> table-fallback connector info creates DFP2/ext-TMDS encoder -> first mode set -> radeon_combios_external_tmds_setup -> RBIOS8(0) on NULL -> panic (boot/mode-set DoS)", "evidence": "run.log decisive lines: combios_get_table_offset(TMDS_POWER_ON) = 0x0000 (NULL bios -> 0 ...) then Segmentation fault (core dumped), exit=139; VERDICT.md full path:line trace; fix_apply.log: one-line fix applies to pristine /usr/src (hunk at 2887)", "kernel_refs": [ "sys/dev/drm/radeon/radeon_combios.c:2888-2891", "sys/dev/drm/radeon/radeon_combios.c:124-132", "sys/dev/drm/radeon/radeon.h:2686", "sys/dev/drm/radeon/r100.c:4056-4059", "sys/dev/drm/radeon/radeon_legacy_encoders.c:985" ], "poc_changes": "harness written from scratch (no seed); exact deref order of the kernel function replicated", "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": 18, "guest_dirty": 0, "build_cmd": "./build.sh (cc -O2 -Wall -o harness harness.c)", "run_cmd": "./run.sh", "code_hash": "87e3f518f97b2b706f8464f5460119eb8a11053759c3476f09e64ef292e686ce", "notes": "Status inconclusive: kernel path hardware-gated (no radeon device on guest); the SIGSEGV harness is the userspace image of the NULL-page fault. Severity Low: needs root-set module param (or PPC Mac) + dead ROM on an IGP board; impact is a panic, not corruption.", "recommended_fix": "Delete the premature rev = RBIOS8(offset) before if (offset) (fix.diff, one line)", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "one-line fix.diff applies cleanly to pristine /usr/src (fix_apply.log); runtime fix validation impossible on this guest (no hardware)", "fix_evidence": "fix.diff; fix_apply.log" } |