⬢ DragonFlyBSD Kernel Audit
DF-3649 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3649",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Source-certain wild read, radeon/ci twin of DF-3587 (amdgpu) / DF-3620 (amdgpu ci). r600_parse_extended_power_table allocates cac_leakage_table.entries with kzalloc(ucNumEntries * entry_size) (r600_dpm.c:1039-1040) and sets count = ucNumEntries (1063). With a crafted usCACLeakageTableOffset whose table declares 0 entries, DragonFly kmalloc(0) returns ZERO_LENGTH_PTR == (void *)-8 (kern_slaballoc.c:193, 886-890) - NON-NULL - so the entries!=NULL guard at ci_dpm.c:2374 passes. The match loops then compute idx = rdev->pm.dpm.dyn_state.cac_leakage_table.count - 1 (ci_dpm.c:2382, 2399); with count==0 the u32 0-1 truncated into u16 idx yields 65535, and entries[65535].vddc / .leakage (2384-2386, 2401-2403) reads ~512KB past a 0-byte allocation - unmapped kernel VA -> page fault/panic (or uncontrolled kernel-memory read if the address happens to be mapped). Requires voltage_control != NONE and any vddc match in vddc_dependency_on_sclk (count>=1 enforced by ci_setup_default_dpm_tables). On-guest harness section [D] demonstrated idx=65535 and the resulting wild address. Kernel path unreachable on this GPU-less guest; inconclusive overall.",
  "exploit_chain": "Crafted VBIOS: SVID2/GPIO VDDC voltage object + a CACLeakageTable with ucNumEntries=0 (kzalloc(0) -> ZERO_LENGTH_PTR passes the non-NULL guard) + any sclk dependency entry whose voltage matches/eclipses the SVI2 table value -> entries[65535] wild read. Primary impact panic; if the wild address were mapped the read leaks into StdVoltageHiSidd/LoSidd which are shipped to the SMC (not directly userspace-visible). DoS-grade.",
  "evidence": "VERDICT.md (full source trace); harness.c + run.log/run.2.log section [D] (count=0 -> idx=65535; wild read address 0x7fff0 (unmapped)); env.txt (guest has no AMD GPU: pciconf 0x1002 count=0, /dev/dri absent, no drm kld); fix.diff",
  "kernel_refs": [
    "sys/dev/drm/radeon/ci_dpm.c:2362",
    "sys/dev/drm/radeon/ci_dpm.c:2374",
    "sys/dev/drm/radeon/ci_dpm.c:2379",
    "sys/dev/drm/radeon/ci_dpm.c:2382",
    "sys/dev/drm/radeon/ci_dpm.c:2384",
    "sys/dev/drm/radeon/ci_dpm.c:2396",
    "sys/dev/drm/radeon/r600_dpm.c:1039",
    "sys/dev/drm/radeon/r600_dpm.c:1063",
    "sys/kern/kern_slaballoc.c:193",
    "sys/kern/kern_slaballoc.c:886"
  ],
  "poc_changes": "n/a \u2014 no seeded PoC for pass-2; harness written fresh (models the exact kernel types; divisors made volatile so -O2 cannot fold the #DE)",
  "attempts": 2,
  "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": 45,
  "guest_dirty": 1,
  "build_cmd": "cc -O2 -Wall -o harness harness.c",
  "run_cmd": "./harness",
  "code_hash": "af83fc943c96cc840bab14bf99787f6e37c43ec42b624d998c2461cc2dad15f2",
  "notes": "pass 2 radeon/ci_dpm.c; twins: DF-3587/DF-3620. Guest virtio-only per task; harness scratch files under /root removed.",
  "recommended_fix": "Require entries != NULL AND count > 0 before using the CAC leakage table in ci_get_std_voltage_value_sidd.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Fix validation would require a CI-class GPU with a crafted VBIOS (baseline panic/corruption) and a single-fix kernel build; the audit guest is virtio-only, so the fix is source-reviewed only (fix.diff).",
  "fix_evidence": "fix.diff in this pack; not applied to sys/ (read-only audit target)."
}