From: Ulf Hansson ulf.hansson@linaro.org
[ Upstream commit 99012014c902cd9ad85fd288d8a107f33a69855e ]
If genpd_alloc_data() allocates data for the default power-states for the genpd, let's make sure to also reset the pointer in the error path. This makes sure a genpd provider driver doesn't end up trying to free the data again, but using an invalid pointer.
Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Reviewed-by: Dhruva Gole d-gole@ti.com Link: https://lore.kernel.org/r/20250402120613.1116711-1-ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org ---
Now I can see that the commit "99012014c9 pmdomain: core: Reset genpd->states to avoid freeing invalid data" is already in the kernel. Let me analyze the backport suitability based on the code changes and the similar commits provided. **YES** This commit should be backported to stable kernel trees based on the following analysis: ## Backport Justification: ### 1. **Critical Bug Fix with Security Implications** The commit fixes a use-after-free/double-free vulnerability in the power domain management core. This is exactly the type of critical bug that stable trees are designed to address. The bug manifests when: - A genpd provider driver calls `pm_genpd_init()` - `genpd_alloc_data()` successfully allocates default power states but then fails later (e.g., in `ida_alloc()`) - The error path leaves `genpd->states` pointing to freed memory - Subsequent cleanup by provider drivers can cause `kfree()` to be called on invalid memory ### 2. **Small, Contained Fix** The code change is minimal and surgical: ```c - if (genpd->free_states == genpd_free_default_power_state) + if (genpd->free_states == genpd_free_default_power_state) { kfree(genpd->states); + genpd->states = NULL; + } ``` This adds only 2 lines of code to reset a pointer to NULL, which has minimal risk of introducing regressions. ### 3. **Comparison with Historical Similar Commits** Looking at the provided similar commits: - **Similar Commit #1** (Status: YES): "Fix error path in pm_genpd_init() when ida alloc fails" - Also fixes error handling in genpd initialization, similar scope and impact - **Similar Commit #4** (Status: YES): "Add missing put_device()" - Also fixes resource cleanup in genpd, small contained fix with `Cc: stable@vger.kernel.org` Both of these accepted backports deal with similar error handling issues in the same subsystem, supporting the case for this commit. ### 4. **Critical Subsystem Impact** The power domain management subsystem is fundamental to kernel operation, especially on embedded systems and SoCs. A use- after-free bug in this core infrastructure could: - Cause kernel panics during device initialization failures - Lead to memory corruption that's difficult to debug - Affect system stability during error recovery scenarios ### 5. **Clear Bug Pattern** The commit follows the established pattern of good backport candidates: - Fixes a clear, reproducible bug (invalid pointer access) - Has minimal code changes with clear intent - Addresses memory management correctness - Authored by the subsystem maintainer (Ulf Hansson) - Includes a detailed commit message explaining the fix ### 6. **Error Path Robustness** This fix improves the robustness of error handling, which is crucial for stable kernel operation. When hardware initialization fails or memory allocation fails, the kernel must handle these conditions gracefully without corrupting memory or crashing. ### 7. **No Architectural Changes** Unlike Similar Commits #2, #3, and #5 (marked NO), this commit doesn't introduce new features, architectural changes, or performance optimizations. It purely fixes a correctness issue in existing error handling logic. The commit represents exactly the type of important bug fix that stable trees should include: small, contained, addresses a real correctness issue, minimal regression risk, and affects a critical kernel subsystem.
drivers/pmdomain/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c index d6c1ddb807b20..7a3bad106e175 100644 --- a/drivers/pmdomain/core.c +++ b/drivers/pmdomain/core.c @@ -2229,8 +2229,10 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd) return 0; put: put_device(&genpd->dev); - if (genpd->free_states == genpd_free_default_power_state) + if (genpd->free_states == genpd_free_default_power_state) { kfree(genpd->states); + genpd->states = NULL; + } free: if (genpd_is_cpu_domain(genpd)) free_cpumask_var(genpd->cpus);