Message ID | 20241203223334.233404-1-djakov@kernel.org (mailing list archive) |
---|---|
State | Not Applicable, archived |
Headers | show |
Series | interconnect: qcom: icc-rpm: Set the count member before accessing the flex array | expand |
On Wed, Dec 04, 2024 at 12:33:34AM +0200, djakov@kernel.org wrote: > From: Georgi Djakov <djakov@kernel.org> > > The following UBSAN error is reported during boot on the db410c board on > a clang-19 build: > > Internal error: UBSAN: array index out of bounds: 00000000f2005512 [#1] PREEMPT SMP > ... > pc : qnoc_probe+0x5f8/0x5fc > ... Really happy to see more coverage of real hardware with compilers that support __counted_by() so that we can start getting these addressed, thanks for this! > The cause of the error is that the counter member was not set before > accessing the annotated flexible array member, but after that. Fix this > by initializing it earlier. > > Reported-by: Linux Kernel Functional Testing <lkft@linaro.org> > Closes: https://lore.kernel.org/r/CA+G9fYs+2mBz1y2dAzxkj9-oiBJ2Acm1Sf1h2YQ3VmBqj_VX2g@mail.gmail.com > Fixes: dd4904f3b924 ("interconnect: qcom: Annotate struct icc_onecell_data with __counted_by") Guess Kees missed one :) > Signed-off-by: Georgi Djakov <djakov@kernel.org> Reviewed-by: Nathan Chancellor <nathan@kernel.org> This is exactly the thing that __builtin_counted_by_ref() is trying to address, as these assignments happen right after the allocation: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fcounted_005fby_005fref > --- > drivers/interconnect/qcom/icc-rpm.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c > index a8ed435f696c..ea1042d38128 100644 > --- a/drivers/interconnect/qcom/icc-rpm.c > +++ b/drivers/interconnect/qcom/icc-rpm.c > @@ -503,6 +503,7 @@ int qnoc_probe(struct platform_device *pdev) > GFP_KERNEL); > if (!data) > return -ENOMEM; > + data->num_nodes = num_nodes; > > qp->num_intf_clks = cd_num; > for (i = 0; i < cd_num; i++) > @@ -597,7 +598,6 @@ int qnoc_probe(struct platform_device *pdev) > > data->nodes[i] = node; > } > - data->num_nodes = num_nodes; > > clk_bulk_disable_unprepare(qp->num_intf_clks, qp->intf_clks); >
diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c index a8ed435f696c..ea1042d38128 100644 --- a/drivers/interconnect/qcom/icc-rpm.c +++ b/drivers/interconnect/qcom/icc-rpm.c @@ -503,6 +503,7 @@ int qnoc_probe(struct platform_device *pdev) GFP_KERNEL); if (!data) return -ENOMEM; + data->num_nodes = num_nodes; qp->num_intf_clks = cd_num; for (i = 0; i < cd_num; i++) @@ -597,7 +598,6 @@ int qnoc_probe(struct platform_device *pdev) data->nodes[i] = node; } - data->num_nodes = num_nodes; clk_bulk_disable_unprepare(qp->num_intf_clks, qp->intf_clks);