NULL boot_ps page-fault panic in cypress_dpm_enable when the VBIOS power table has no BOOT-classified state (or dpm.init failed) β cypress twin of DF-4022/DF-3972/DF-3754
Summary
boot_ps is assigned only under the BOOT classification. Two crafted-VBIOS shapes reach a NULL deref: (a) no BOOT-classified state -> cypress_force_mc_use_s0(rdev, NULL) -> rv770_get_ps(NULL) reads rps->ps_priv at NULL+offset -> page fault at DPM enable (default-on at boot); (b) dpm_init failed but the double-swallowed error lets radeon_dpm_enable run on the kzalloc-zeroed eg_pi and cypress_init_smc_table(rdev, NULL) -> same NULL-page read. cypress_dpm_disable carries the same latent deref. NULL-guard fix (+ honor dpm.init long-term).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4118 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.5 KB | β raw | |
| VERDICT.md | β | 2.5 KB | β raw | |
| fix.diff | β | 717 B | view raw | |
| env.txt | β | 583 B | view raw | |
| manifest.json | β | 1.2 KB | view raw | |
| verdict.json | β | 3.0 KB | view raw |
DF-4118 β NULL boot_ps dereference panic in cypress_dpm_enable (cypress dispatch; twin of DF-4022/3972/3754/3953/3646/3610) ==================================================================== File: sys/dev/drm/radeon/cypress_dpm.c β pass 2 (GLM 5.3).
rdev->pm.dpm.boot_ps is set ONLY at rv770_dpm.c:2172-2173 under ATOM_PPLIB_CLASSIFICATION_BOOT. Two crafted-VBIOS shapes reach cypress_dpm_enable with boot_ps == NULL:
(a) no BOOT-classified state (parse OK, init fully initializes eg_pi->dynamic_ac_timing=true at cypress_dpm.c:2119): cypress_dpm_enable :1837-1839 -> cypress_force_mc_use_s0(rdev, NULL) -> rv770_get_ps(NULL) reads rps->ps_priv at NULL+offset (rv770_dpm.c:53-57) -> kernel page fault. (b) cypress_dpm_init fails (missing PowerPlayInfo header / DF-4117 alloc failure): radeon_pm.c:1448 IGNORES the error, evergreen.c:5235 calls radeon_pm_init() as a statement; enable runs on the kzalloc-zeroed eg_pi (dynamic_ac_timing=0 skips (a)) and, when SMC firmware uploads, :1878 cypress_init_smc_table(rdev, NULL) -> cypress_populate_smc_initial_state:1242 -> rv770_get_ps(NULL).
Panic at module load / boot on the affected card (DPM is default-on); persistent boot DoS via VBIOS/option-ROM level crafting, attacker- controlled precondition is physical/vBIOS access β same acceptance basis as the filed btc/rv770/ni twins (DF-3972/4022/3754). No evergreen hardware on the audit guest => runtime inconclusive; source-level certain. fix.diff: early boot_ps guards in cypress_dpm_enable/cypress_dpm_disable.
DF-4118 VERDICT β NULL boot_ps page fault in cypress_dpm_enable
STATUS: inconclusive (runtime hardware-gated); mechanism source-certain. impact ceiling (not demonstrated): kernel page-fault panic at module load/boot. confidence: certain.
CHAIN (path:line):
* boot_ps is assigned ONLY at rv770_dpm.c:2172-2173
(if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)
rdev->pm.dpm.boot_ps = rps;) inside
rv7xx_parse_pplib_non_clock_info.
* rv770_get_ps(rps) is an unguarded return rps->ps_priv
(rv770_dpm.c:53-57) β NULL rps reads at NULL + offsetof(ps_priv).
* Path (a) β no BOOT-classified state in an otherwise-valid power
table: cypress_dpm_init completes (dynamic_ac_timing=true at
cypress_dpm.c:2119; voltage/mvdd flags from VBIOS),
cypress_dpm_enable:1837 if (eg_pi->dynamic_ac_timing) ->
:1839 cypress_force_mc_use_s0(rdev, boot_ps=NULL) ->
:1184 rv770_get_ps(NULL) -> page fault. Runs BEFORE any code that
could fail gracefully.
* Path (b) β cypress_dpm_init itself fails (atom_parse_data_header
fails on missing/garbage PowerPlayInfo at rv770_dpm.c:2279-2282, or
DF-4117's alloc failure): radeon_pm.c:1448 ignores .dpm.init's
error and evergreen.c:5235 ignores radeon_pm_init's error, so
radeon_dpm_enable (radeon_pm.c:1453) still executes with the
kzalloc-zeroed eg_pi (all feature flags 0): the :1837 branch is
skipped, and with SMC firmware present the flow reaches
:1878 cypress_init_smc_table(rdev, NULL) ->
cypress_populate_smc_initial_state:1242 rv770_get_ps(NULL) ->
page fault. (Without SMC firmware rv770_upload_firmware at :1867
fails first and returns β the DF-4023 graceful variant.)
* cypress_dpm_disable:1953 cypress_force_mc_use_s1(rdev, boot_ps)
has the same latent deref if ever reached with dpm enabled.
Twin of DF-4022 (rv770), DF-3972 (btc), DF-3754 (ni); the knowns for THIS file (DF-1385/1386/1387) do not cover it.
FIX: fix.diff β early if (boot_ps == NULL) return -EINVAL; guards in
cypress_dpm_enable and cypress_dpm_disable. Kernel-level validation
impossible here (no evergreen GPU): fix_status not_testable.
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testableDiff authored but kernel-level validation requires evergreen hardware absent from the audit guest.
fix.diff; VERDICT.md
Confirmed kernel references
- sys/dev/drm/radeon/cypress_dpm.c:1811
- sys/dev/drm/radeon/cypress_dpm.c:1837
- sys/dev/drm/radeon/cypress_dpm.c:1839
- sys/dev/drm/radeon/cypress_dpm.c:1878
- sys/dev/drm/radeon/cypress_dpm.c:1184
- sys/dev/drm/radeon/cypress_dpm.c:1242
- sys/dev/drm/radeon/cypress_dpm.c:1953
- sys/dev/drm/radeon/rv770_dpm.c:53
- sys/dev/drm/radeon/rv770_dpm.c:2172
- sys/dev/drm/radeon/radeon_pm.c:1448
- sys/dev/drm/radeon/evergreen.c:5235
Detail
Exploit chain
Crafted/missing BOOT-state VBIOS on an evergreen-family card -> kernel page-fault panic at radeon attach (DPM default-on) -> persistent boot DoS; precondition is physical/vBIOS access (option-ROM/vBIOS flash), matching the acceptance basis of the filed btc/rv770/ni twins.
Evidence (decisive lines)
VERDICT.md (both sub-paths with path:line); fix.diff (early boot_ps guards); env.txt (hardware absence)
PoC changes
No seed PoC; hardware-gated (no AMD evergreen GPU on the audit guest).
Verified recommended fix
Reject enable/disable when rdev->pm.dpm.boot_ps == NULL (fix.diff guards in cypress_dpm_enable/cypress_dpm_disable); long-term: honor dpm.init failure in radeon_pm.c.
Verdict
Source-level certain, runtime hardware-gated. rdev->pm.dpm.boot_ps is set only under ATOM_PPLIB_CLASSIFICATION_BOOT (rv770_dpm.c:2172-2173); two crafted-VBIOS shapes reach a NULL deref through this file's dispatch: (a) power table parses but no BOOT-classified state -> cypress_dpm_enable:1837-1839 cypress_force_mc_use_s0(rdev, NULL) -> rv770_get_ps(NULL) reads rps->ps_priv at NULL+offset (rv770_dpm.c:53-57) -> page fault; (b) cypress_dpm_init fails (missing PowerPlayInfo header / DF-4117 alloc failure) but radeon_pm.c:1448 discards .dpm.init's error and evergreen.c:5235 calls radeon_pm_init() as a statement, so radeon_dpm_enable executes on the kzalloc-zeroed eg_pi and, with SMC firmware present, cypress_init_smc_table(rdev, NULL) at cypress_dpm.c:1878 -> cypress_populate_smc_initial_state:1242 -> rv770_get_ps(NULL) -> page fault at boot/module-load. cypress_dpm_disable:1953 has the same latent deref. Twin of DF-4022/3972/3754; this file's knowns (DF-1385/1386/1387) do not cover it.
No comments yet.