dcn_bw_notify_pplib_of_wm_ranges dereferences unchecked res_pool->pp_smu (kzalloc-failure NULL) β probe-time panic on DCN1
Summary
The function loads pp = dc->res_pool->pp_smu and dereferences pp->set_wm_ranges without ever checking pp itself. The sole assignment returns NULL on kzalloc failure and no check follows; the probe-time call is unconditional. Raven-APU systems: kernel memory pressure at the instant of construct's kzalloc turns driver probe into a NULL-pointer panic at boot. Upstream carries the same latent pattern. NULL-guard fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4272 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.8 KB | β raw | |
| VERDICT.md | β | 1.8 KB | β raw | |
| fix.diff | β | 855 B | view raw | |
| verdict.json | β | 2.6 KB | view raw | |
| env.txt | β | 700 B | view raw |
DF-4272 β dcn_bw_notify_pplib_of_wm_ranges() dereferences res_pool->pp_smu without a NULL check
File: sys/dev/drm/amd/display/dc/calcs/dcn_calcs.c:1399-1407 (DCN1
bandwidth calc engine).
What
void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc)
{
struct pp_smu_funcs_rv *pp = dc->res_pool->pp_smu;
...
if (!pp->set_wm_ranges) /* :1406 - pp itself unchecked */
return;
dc->res_pool->pp_smu is assigned exactly once, in
dcn10_resource_construct():
pool->base.pp_smu = dcn10_pp_smu_create(ctx); /* dcn10_resource.c:1352 */
...
if (!dc->debug.disable_pplib_wm_range) {
dc->res_pool = &pool->base;
dcn_bw_notify_pplib_of_wm_ranges(dc); /* dcn10_resource.c:1357 */
}
and dcn10_pp_smu_create() is a plain kzalloc() that returns NULL on
allocation failure (dcn10_resource.c:858-865):
struct pp_smu_funcs_rv *dcn10_pp_smu_create(struct dc_context *ctx)
{
struct pp_smu_funcs_rv *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL);
if (!pp_smu)
return pp_smu; /* NULL */
There is no NULL check anywhere between the create and the dereference, so
an allocation failure during amdgpu DCN1 (Raven APU) driver probe takes a
NULL-pointer read at pp->set_wm_ranges β kernel panic at probe time. The
second call site, dcn10_hw_sequencer.c:2303 (optimize_shared_resources),
would fault the same way whenever it is reached with a NULL pp_smu.
Impact
Boot/probe-time panic under kernel memory pressure on Raven-APU systems (amdgpu with DCN1). No privilege needed by an attacker beyond the ability to influence allocation timing (or simply an unlucky boot); OOM-gated, hardware-gated. Severity Low. CWE-476.
Fix
if (!pp || !pp->set_wm_ranges) return; (fix.diff).
VERDICT - DF-4272 (dcn_bw_notify_pplib_of_wm_ranges NULL pp_smu deref)
Status: untested - the audit guest has no AMD DCN1 (Raven) GPU (env.txt); the code path is source-certain.
Trace
dcn_bw_notify_pplib_of_wm_ranges()(dcn_calcs.c:1401):struct pp_smu_funcs_rv *pp = dc->res_pool->pp_smu;- First dereference of
pp:if (!pp->set_wm_ranges)(dcn_calcs.c:1406) -ppitself is never NULL-checked. - Sole assignment:
pool->base.pp_smu = dcn10_pp_smu_create(ctx);(dcn10_resource.c:1352), whose implementation returns NULL on kzalloc failure (dcn10_resource.c:858-865). No NULL check follows the create. - Unconditional call site (unless the debug flag
disable_pplib_wm_rangeis set): dcn10_resource.c:1353-1357, insidedcn10_resource_construct()during driver probe. Second site: dcn10_hw_sequencer.c:2303 (optimize_shared_resources), reached later in DC bring-up.
Impact
NULL pointer read β panic during amdgpu probe under memory pressure on DCN1-bearing APUs (Raven). Trigger is environmental (kzalloc OOM at the wrong instant), not attacker-directed in the usual sense; the guest has no such hardware so no reproduction is possible. Low severity, certain code path, speculative trigger. Note: the same latent pattern exists in the upstream Linux DC code of this vintage.
Fix
One-line guard (fix.diff). A NULL-check-only change: no behavioral difference on the success path.
Fix validation
Not possible on this guest (no Raven 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_testableFix validation requires DCN1 hardware; the guest has none.
fix.diff; VERDICT.md
Confirmed kernel references
- sys/dev/drm/amd/display/dc/calcs/dcn_calcs.c:1401
- sys/dev/drm/amd/display/dc/calcs/dcn_calcs.c:1406
- sys/dev/drm/amd/display/dc/dcn10/dcn10_resource.c:1352
- sys/dev/drm/amd/display/dc/dcn10/dcn10_resource.c:1357
- sys/dev/drm/amd/display/dc/dcn10/dcn10_resource.c:858
- sys/dev/drm/amd/display/dc/dcn10/dcn10_resource.c:865
- sys/dev/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c:2303
Detail
Evidence (decisive lines)
VERDICT.md trace (create->store->deref chain with path:line); dcn10_resource.c:858-865 (NULL return), :1352-1357 (unchecked store + probe-time call); dcn_calcs.c:1401-1406
PoC changes
No PoC (no DCN1 hardware in guest); analysis pack.
Verified recommended fix
if (!pp || !pp->set_wm_ranges) return; in dcn_bw_notify_pplib_of_wm_ranges().
Verdict
Source-certain NULL-deref path, OOM-gated trigger. dcn_bw_notify_pplib_of_wm_ranges() (dcn_calcs.c:1401) loads pp = dc->res_pool->pp_smu and dereferences pp->set_wm_ranges at :1406 without checking pp. The sole assignment is pool->base.pp_smu = dcn10_pp_smu_create(ctx) (dcn10_resource.c:1352), which returns NULL on kzalloc failure (dcn10_resource.c:858-865); no NULL check anywhere between create and use. Call sites: dcn10_resource.c:1353-1357 (probe, unconditional unless disable_pplib_wm_range) and dcn10_hw_sequencer.c:2303 (optimize_shared_resources). Allocation failure during amdgpu DCN1 probe -> NULL read -> panic at boot/probe on Raven APU systems. Guest has no DCN1 GPU (env.txt), so not kernel-reproduced; trigger requires kernel memory pressure at the wrong instant (speculative trigger, certain code path). Upstream Linux DC of this vintage carries the same latent pattern.
No comments yet.