summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJie Gan <jie.gan@oss.qualcomm.com>2026-05-11 07:19:18 +0300
committerSuzuki K Poulose <suzuki.poulose@arm.com>2026-05-19 16:24:55 +0300
commit1563ae33dc4f5ebac96b93af2ef72e72aaaa31ae (patch)
tree519bfa4fbaccb658b13d93e7c6b5fcc2419b1fdb
parenta5dd853fb7774c9543aed272a8614c15ebce3173 (diff)
downloadlinux-1563ae33dc4f5ebac96b93af2ef72e72aaaa31ae.tar.xz
coresight: platform: defer connection counter increment until alloc succeeds
coresight_add_out_conn() increments nr_outconns before calling devm_krealloc_array() and again before devm_kmalloc(). If either allocation fails, the counter is already bumped while the corresponding array entry is NULL or uninitialized garbage. coresight_add_in_conn() has the same problem with nr_inconns and devm_krealloc_array(). In both cases the probe returns -ENOMEM, which causes coresight_get_platform_data() to call coresight_release_platform_data() for cleanup. That function iterates up to nr_outconns (or nr_inconns) entries and dereferences each pointer unconditionally, hitting the NULL or garbage entry and panicking instead of failing gracefully. Fix by moving the counter increments to after all allocations succeed, so the struct is always consistent on any error path. Fixes: 3d4ff657e454 ("coresight: Dynamically add connections") Fixes: e3f4e68797a9 ("coresight: Store in-connections as well as out-connections") Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com> Reviewed-by: James Clark <james.clark@linaro.org> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20260511-fix-ref-count-issue-v1-1-99d647810d3c@oss.qualcomm.com
-rw-r--r--drivers/hwtracing/coresight/coresight-platform.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c
index e337b6e2bf32..93c2d075cad6 100644
--- a/drivers/hwtracing/coresight/coresight-platform.c
+++ b/drivers/hwtracing/coresight/coresight-platform.c
@@ -45,9 +45,8 @@ coresight_add_out_conn(struct device *dev,
}
}
- pdata->nr_outconns++;
pdata->out_conns =
- devm_krealloc_array(dev, pdata->out_conns, pdata->nr_outconns,
+ devm_krealloc_array(dev, pdata->out_conns, pdata->nr_outconns + 1,
sizeof(*pdata->out_conns), GFP_KERNEL);
if (!pdata->out_conns)
return ERR_PTR(-ENOMEM);
@@ -63,7 +62,8 @@ coresight_add_out_conn(struct device *dev,
* used right away.
*/
*conn = *new_conn;
- pdata->out_conns[pdata->nr_outconns - 1] = conn;
+ pdata->out_conns[pdata->nr_outconns] = conn;
+ pdata->nr_outconns++;
return conn;
}
EXPORT_SYMBOL_GPL(coresight_add_out_conn);
@@ -86,13 +86,13 @@ int coresight_add_in_conn(struct coresight_connection *out_conn)
return 0;
}
- pdata->nr_inconns++;
pdata->in_conns =
- devm_krealloc_array(dev, pdata->in_conns, pdata->nr_inconns,
+ devm_krealloc_array(dev, pdata->in_conns, pdata->nr_inconns + 1,
sizeof(*pdata->in_conns), GFP_KERNEL);
if (!pdata->in_conns)
return -ENOMEM;
- pdata->in_conns[pdata->nr_inconns - 1] = out_conn;
+ pdata->in_conns[pdata->nr_inconns] = out_conn;
+ pdata->nr_inconns++;
return 0;
}
EXPORT_SYMBOL_GPL(coresight_add_in_conn);