rockchip_clk_register_cpuclk_multi_pll() registers an embedded notifier block before duplicating the rate table. If that allocation fails, the error path frees the notifier owner and unregisters the watched composite clock without removing the notifier. The common clock framework retains both pointers in its global notifier state. A later rate change walks that state in __clk_notify() and reads the freed watched struct clk before it can compare the clock core. The notifier chain also retains the notifier block embedded in the freed cpuclk. Unregister the notifier before freeing either object. This mirrors the rollback already used by the adjacent rockchip_clk_register_cpuclk() helper for its equivalent post-registration rate-table allocation failure. With controlled allocation failure injection, a later rate change produced two KASAN use-after-free reports in __clk_notify() in each of three runs. The same three runs completed without a kernel diagnostic with this change. Fixes: 826eaa8f5bac ("clk: rockchip: Implement rockchip_clk_register_armclk_multi_pll()") Cc: stable@vger.kernel.org Assisted-by: Codex:GPT-5 Signed-off-by: Yibo Tan --- drivers/clk/rockchip/clk-cpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index eb6b8b878..2de7f2b4f 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c @@ -544,6 +544,7 @@ struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name, GFP_KERNEL); if (!cpuclk->rate_table) { ret = -ENOMEM; + clk_notifier_unregister(hw->clk, &cpuclk->clk_nb); goto free_cpuclk; } } base-commit: 04721208427536c0f70db0efc5362c7f5a4997c9 -- 2.39.5