dcn10 construct() OOM error path: dcn10_pp_smu_create() result never checked β NULL pp_smu dereferenced via dcn_bw_notify_pplib_of_wm_ranges (probe-time panic); dcn10_create_resource_pool leaks the pool allocation on construct failure
Summary
pp_smu is the only unchecked allocation in construct() whose result is dereferenced during construction: the production default takes the path that calls dcn_bw_notify_pplib_of_wm_ranges which does 'if (!pp->set_wm_ranges)' on the NULL - panic under memory pressure instead of the graceful goto-fail every sibling allocation (15 of them) has. Separately, create_resource_pool never kfrees the several-KB pool when construct fails. NULL-check + kfree-on-fail fix (the DF-4215 dc.c twin).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4313 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 2.6 KB | β raw | |
| VERDICT.md | β | 3.0 KB | β raw | |
| fix.diff | β | 497 B | view raw | |
| env.txt | β | 694 B | view raw | |
| verdict.json | β | 3.2 KB | view raw | |
| manifest.json | β | 1.5 KB | view raw |
DF-4313 β dcn10 construct() OOM error path: unchecked pp_smu (NULL-deref panic) + leaked pool
What (two defects in the dcn10_resource_pool construction error path):
-
dcn10_resource.c:1350
pool->base.pp_smu = dcn10_pp_smu_create(ctx);The return value is NOT checked (dcn10_pp_smu_create, dcn10_resource.c:858-867, returns NULL on kzalloc failure). Construction continues, and at dcn10_resource.c:1355-1357:if (!dc->debug.disable_pplib_wm_range) { dc->res_pool = &pool->base; dcn_bw_notify_pplib_of_wm_ranges(dc); }debug_defaults_drv.disable_pplib_wm_range = false (dcn10_resource.c:536), so on every production driver dcn_bw_notify_pplib_of_wm_ranges() runs and dereferences
dc->res_pool->pp_smuunconditionally:dcn_calcs.c:1399 struct pp_smu_funcs_rv *pp = dc->res_pool->pp_smu; dcn_calcs.c:1403 if (!pp->set_wm_ranges) <-- NULL deref
=> GPU-probe-time NULL-deref panic under memory pressure instead of the graceful fallback every other allocation in construct() has. (dcn10_hw_sequencer.c:2303 calls the same function later, same deref.)
-
dcn10_resource.c:1482-1497 dcn10_create_resource_pool(): when construct() fails (any of its many goto fail paths), destruct(pool) frees the pool MEMBERS but the
poolallocation itself (kzalloc at :1486, sizeof(struct dcn10_resource_pool), several KB) is leaked - kfree(dcn10_pool) exists only in dcn10_destroy_resource_pool (:1127).
Class/impact: OOM-gated boot/probe-time kernel NULL-deref panic (CWE-476) + memory leak (CWE-401). Identical class to DF-4215 (dc.c construct() OOM path, rated Low). Requires allocation failure during amdgpu DC pool construction on a Raven-class APU - not attacker-steerable timing, severity Low (robustness).
Reachability on this audit guest: NOT reachable - no AMD GPU (env.txt), amdgpu never attaches. Verdict: inconclusive (code-certain, hardware-gated).
Files: fix.diff both one-line fixes (checked pp_smu -> goto fail; kfree(pool) on create failure); git apply --check clean env.txt guest hardware-absence evidence verdict.json machine verdict
Manual validation path for maintainers with a Raven APU: fail-inject kzalloc in dcn10_pp_smu_create (or boot with artificially constrained kmem): pre-fix kernel panics in dcn_bw_notify_pplib_of_wm_ranges; post-fix amdgpu probe fails gracefully ("DC: failed to create pp_smu!") and the pool allocation is freed.
VERDICT β DF-4313 dcn10 construct() OOM error-path defects
STATUS: inconclusive (code-certain defect; trigger requires DCN1 ASIC + allocation failure at pool construction - neither available on the audit guest) REPRODUCED: 0
ANALYSIS CONFIRMATION (static, line-accurate):
-
NULL-deref path: - dcn10_resource.c:1350 assigns pool->base.pp_smu without a NULL check; dcn10_pp_smu_create (dcn10_resource.c:858-867) returns NULL when kzalloc(sizeof(struct pp_smu_funcs_rv)) fails. - Every other allocation in construct() is checked and goto fail (clock sources :1277-1283, dccg :1286, dmcu :1296, abm :1306, irqs :1364, hubps/ipps/dpps/opps/tgs :1378-1416, aux/hw_i2c :1421-1435, mpc :1449, hubbub :1456). pp_smu is the ONE unchecked allocation whose result is dereferenced during construction. - Production defaults take the call: debug_defaults_drv (dcn10_resource.c:522-548) has .disable_pplib_wm_range = false (line 536); construct() then executes dc->res_pool = &pool->base; dcn_bw_notify_pplib_of_wm_ranges(dc); (dcn10_resource.c:1355-1357). - dcn_calcs.c:1399
pp = dc->res_pool->pp_smu;and :1403if (!pp->set_wm_ranges)dereference pp before any NULL check - there is none in the function. dm_pp_get_funcs_rv (amdgpu_dm_pp_smu.c:565-574) fills set_wm_ranges unconditionally, so a successful alloc is fine; only the NULL case faults. - Same pattern reachable later from dcn10_hw_sequencer.c:2303. -
Leak path: - dcn10_create_resource_pool (dcn10_resource.c:1482-1497): on construct() failure the function returns NULL after destruct(pool); destruct (dcn10_resource.c:869-961) frees members only; the pool allocation leaks. kfree(pool) exists solely in dcn10_destroy_resource_pool (dcn10_resource.c:1122-1129).
Severity rationale: OOM-gated NULL-deref panic at GPU probe + small one-shot leak; requires memory exhaustion during amdgpu DC bring-up on a Raven-class APU. Low (robustness), same class/severity as DF-4215.
Guest testability: none (no AMD PCI device on the audit guest, env.txt); amdgpu.ko never probes, construct() never runs. No PoC authored; the defect is proven by code path enumeration above.
Fix (fix.diff, git apply --check clean): - check pool->base.pp_smu == NULL -> dm_error + goto fail (consistent with the 15 other checked allocations in construct()); - kfree(pool) in dcn10_create_resource_pool's failure branch. Both validated by inspection: goto fail runs destruct() which handles a NULL pp_smu (kfree(NULL) safe per linuxkpi slab.h:39-43) and all partially-created members.
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_testablenot_applicable: no DCN1 hardware available for a live baseline/patched run; fix verified by inspection against destruct()'s NULL-safe teardown and by git apply --check.
findings/poc/DF-4313/fix.diff
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md (line-accurate path enumeration: 1350 -> 1355-1357 -> dcn_calcs.c:1399/1403; leak at 1486/1493), README.md (fail-inject manual test for maintainers), env.txt (guest amd-gpu-count=0), fix.diff
PoC changes
No executable PoC authored: requires DCN1 silicon plus a kzalloc failure inside construct(); the audit guest has no AMD PCI device. Static proof documented instead.
Verified recommended fix
NULL-check dcn10_pp_smu_create() (goto fail) and kfree(pool) when construct() fails in dcn10_create_resource_pool (see fix.diff).
Verdict
Two code-certain defects in the dcn10 pool construction error path, neither executable on the audit guest (no AMD GPU; construct() requires amdgpu attach to a Raven-class DCN1 ASIC): (1) dcn10_resource.c:1350 assigns pool->base.pp_smu from dcn10_pp_smu_create() without a NULL check - it is the only unchecked allocation in construct() whose result is dereferenced during construction; with production defaults (disable_pplib_wm_range=false, dcn10_resource.c:536) construct() calls dcn_bw_notify_pplib_of_wm_ranges (dcn10_resource.c:1355-1357) which dereferences pp_smu at dcn_calcs.c:1399/1403 (if (!pp->set_wm_ranges)) with no NULL guard - an allocation failure turns into a kernel NULL-deref panic at GPU probe instead of the graceful fallback all sibling allocations have; (2) dcn10_create_resource_pool (dcn10_resource.c:1493-1496) leaks the several-KB pool allocation when construct() fails, since destruct() frees only the members. Same class as DF-4215 (Low, OOM-gated). fix.diff adds the missing check (goto fail, consistent with the other 15 checks) and kfree(pool) on the failure branch; git apply --check clean; destruct() is NULL-safe for pp_smu (linuxkpi kfree checks NULL, slab.h:39-43).
No comments yet.