clk: zynq: handle kasprintf() failure in periph_clk registration

zynq_clk_register_periph_clk() ignores the return value of the two
kasprintf() calls used to build the mux and divider clock names, and
passes the resulting (possibly NULL) pointers straight into
clk_register_mux(), clk_register_divider() and clk_register_gate() as
the clock '"'name'"' argument.  On allocation failure that name later
gets dereferenced by the clock framework (e.g. in debugfs name
formatting), causing a NULL-pointer dereference.

Check both kasprintf() returns.  On failure unwind any allocated name
buffer and the spinlock, then fall through to the existing err label
which sets clks[] to ERR_PTR(-ENOMEM).  Freeing the spinlock on the
error path is correct here because no clk_register_*() call has had
a chance to take ownership of it; the success path intentionally
hands it off to the registered clocks.

The neighbouring zynq_clk_register_fclk() in the same file already
uses this per-allocation goto-label cleanup pattern; this change
brings periph_clk into line with it.

Signed-off-by: William Theesfeld <william@theesfeld.net>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Reviewed-by: Michal Simek <michal.simek@amd.com>
Signed-off-by: Brian Masney <bmasney@redhat.com>
This commit is contained in:
William Theesfeld 2026-06-01 16:35:00 -04:00 committed by Brian Masney
parent ff29670735
commit d4d0d335e8

View File

@ -186,7 +186,11 @@ static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0,
spin_lock_init(lock);
mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name0);
if (!mux_name)
goto err_mux_name;
div_name = kasprintf(GFP_KERNEL, "%s_div", clk_name0);
if (!div_name)
goto err_div_name;
clk_register_mux(NULL, mux_name, parents, 4,
CLK_SET_RATE_NO_REPARENT, clk_ctrl, 4, 2, 0, lock);
@ -205,6 +209,10 @@ static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0,
return;
err_div_name:
kfree(mux_name);
err_mux_name:
kfree(lock);
err:
clks[clk0] = ERR_PTR(-ENOMEM);
if (two_gates)