* [PATCH] ASoC: qdsp6: q6routing: Fix memory leak on probe failure
@ 2026-10-25 8:02 Tang Bin
2026-10-27 14:44 ` Srinivas Kandagatla
0 siblings, 1 reply; 5+ messages in thread
From: Tang Bin @ 2026-10-25 8:02 UTC (permalink / raw)
To: srini, lgirdwood, broonie, perex, tiwai
Cc: linux-sound, linux-arm-msm, linux-kernel, tangbin
routing_data is allocated with kzalloc() (not devm_kzalloc) and stored
in a global static pointer. If devm_snd_soc_register_component() fails,
the probe function returns the error directly without freeing
routing_data. Since the remove callback is not invoked on probe failure,
the allocated memory is leaked.
On a probe retry, a new routing_data would be allocated, overwriting
the global pointer and losing the reference to the previous allocation.
Fix this by checking the return value of
devm_snd_soc_register_component() and freeing routing_data on failure.
Fixes: e3a33673e845 ("ASoC: qdsp6: q6routing: Add q6routing driver")
Signed-off-by: Tang Bin <tangbin@cmss.chinamobile.com>
---
sound/soc/qcom/qdsp6/q6routing.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
index d076c99f1..fb633efd8 100644
--- a/sound/soc/qcom/qdsp6/q6routing.c
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -1208,6 +1208,7 @@ static const struct snd_soc_component_driver msm_soc_routing_component = {
static int q6pcm_routing_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ int ret;
routing_data = kzalloc_obj(*routing_data);
if (!routing_data)
@@ -1218,8 +1219,13 @@ static int q6pcm_routing_probe(struct platform_device *pdev)
mutex_init(&routing_data->lock);
dev_set_drvdata(dev, routing_data);
- return devm_snd_soc_register_component(dev, &msm_soc_routing_component,
+ ret = devm_snd_soc_register_component(dev, &msm_soc_routing_component,
NULL, 0);
+ if (ret) {
+ kfree(routing_data);
+ routing_data = NULL;
+ }
+ return ret;
}
static void q6pcm_routing_remove(struct platform_device *pdev)
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] ASoC: qdsp6: q6routing: Fix memory leak on probe failure
2026-10-25 8:02 [PATCH] ASoC: qdsp6: q6routing: Fix memory leak on probe failure Tang Bin
@ 2026-10-27 14:44 ` Srinivas Kandagatla
2026-10-28 1:57 ` [PATCH v2] " Tang Bin
0 siblings, 1 reply; 5+ messages in thread
From: Srinivas Kandagatla @ 2026-10-27 14:44 UTC (permalink / raw)
To: Tang Bin, srini, lgirdwood, broonie, perex, tiwai
Cc: linux-sound, linux-arm-msm, linux-kernel
On 10/25/26 8:02 AM, Tang Bin wrote:
> routing_data is allocated with kzalloc() (not devm_kzalloc) and stored
> in a global static pointer. If devm_snd_soc_register_component() fails,
> the probe function returns the error directly without freeing
> routing_data. Since the remove callback is not invoked on probe failure,
> the allocated memory is leaked.
>
> On a probe retry, a new routing_data would be allocated, overwriting
> the global pointer and losing the reference to the previous allocation.
>
> Fix this by checking the return value of
> devm_snd_soc_register_component() and freeing routing_data on failure.
>
> Fixes: e3a33673e845 ("ASoC: qdsp6: q6routing: Add q6routing driver")
> Signed-off-by: Tang Bin <tangbin@cmss.chinamobile.com>
> ---
> sound/soc/qcom/qdsp6/q6routing.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
> index d076c99f1..fb633efd8 100644
> --- a/sound/soc/qcom/qdsp6/q6routing.c
> +++ b/sound/soc/qcom/qdsp6/q6routing.c
> @@ -1208,6 +1208,7 @@ static const struct snd_soc_component_driver msm_soc_routing_component = {
> static int q6pcm_routing_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> + int ret;
>
> routing_data = kzalloc_obj(*routing_data);
> if (!routing_data)
> @@ -1218,8 +1219,13 @@ static int q6pcm_routing_probe(struct platform_device *pdev)
> mutex_init(&routing_data->lock);
> dev_set_drvdata(dev, routing_data);
>
> - return devm_snd_soc_register_component(dev, &msm_soc_routing_component,
> + ret = devm_snd_soc_register_component(dev, &msm_soc_routing_component,
> NULL, 0);
> + if (ret) {
how about something like this:
diff --git a/sound/soc/qcom/qdsp6/q6routing.c
b/sound/soc/qcom/qdsp6/q6routing.c
index d076c99f197f..4816d4b9a48c 100644
--- a/sound/soc/qcom/qdsp6/q6routing.c
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -1209,7 +1209,7 @@ static int q6pcm_routing_probe(struct
platform_device *pdev)
{
struct device *dev = &pdev->dev;
- routing_data = kzalloc_obj(*routing_data);
+ routing_data = devm_kzalloc_obj(dev, *routing_data);
if (!routing_data)
return -ENOMEM;
@@ -1224,7 +1224,6 @@ static int q6pcm_routing_probe(struct
platform_device *pdev)
static void q6pcm_routing_remove(struct platform_device *pdev)
{
- kfree(routing_data);
routing_data = NULL;
}
> + kfree(routing_data);
> + routing_data = NULL;
> + }
> + return ret;
> }
>
> static void q6pcm_routing_remove(struct platform_device *pdev)
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2] ASoC: qdsp6: q6routing: Fix memory leak on probe failure
2026-10-27 14:44 ` Srinivas Kandagatla
@ 2026-10-28 1:57 ` Tang Bin
2026-10-28 2:10 ` sashiko-bot
2026-10-28 10:25 ` Srinivas Kandagatla
0 siblings, 2 replies; 5+ messages in thread
From: Tang Bin @ 2026-10-28 1:57 UTC (permalink / raw)
To: Srinivas Kandagatla, srini, lgirdwood, broonie, perex, tiwai
Cc: linux-sound, linux-arm-msm, linux-kernel, Tang Bin
routing_data is allocated with kzalloc() and stored in a global static
pointer. If devm_snd_soc_register_component() fails, the probe function
returns directly without freeing routing_data. Since the remove callback
is not invoked on probe failure, this leads to a memory leak. On a probe
retry, a new routing_data overwrites the global pointer, permanently
losing the previous allocation.
Fix this by switching to devm_kzalloc_obj() for the allocation. This
ensures the memory is automatically freed by the device core if probe
fails or when the driver is unbound. Consequently, the manual kfree()
in the remove callback is no longer needed and must be removed to avoid
a double-free.
Fixes: e3a33673e845 ("ASoC: qdsp6: q6routing: Add q6routing driver")
Signed-off-by: Tang Bin <tangbin@cmss.chinamobile.com>
---
Changes in v2:
- Use devm_kzalloc_obj() to let the device core manage the memory
lifecycle, as suggested by Srinivas Kandagatla. This eliminates the
need for manual error handling and prevents a double-free in remove.
sound/soc/qcom/qdsp6/q6routing.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
index d076c99f1..4816d4b9a 100644
--- a/sound/soc/qcom/qdsp6/q6routing.c
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -1209,7 +1209,7 @@ static int q6pcm_routing_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- routing_data = kzalloc_obj(*routing_data);
+ routing_data = devm_kzalloc_obj(dev, *routing_data);
if (!routing_data)
return -ENOMEM;
@@ -1224,7 +1224,6 @@ static int q6pcm_routing_probe(struct platform_device *pdev)
static void q6pcm_routing_remove(struct platform_device *pdev)
{
- kfree(routing_data);
routing_data = NULL;
}
--
2.52.0.windows.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2] ASoC: qdsp6: q6routing: Fix memory leak on probe failure
2026-10-28 1:57 ` [PATCH v2] " Tang Bin
@ 2026-10-28 2:10 ` sashiko-bot
2026-10-28 10:25 ` Srinivas Kandagatla
1 sibling, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-10-28 2:10 UTC (permalink / raw)
To: Tang Bin; +Cc: linux-sound
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Critical] ASoC: qdsp6: q6routing: dangling routing_data on q6pcm_routing_probe() failure
- [Low] ASoC: qdsp6: call to undeclared devm_kzalloc_obj() in q6pcm_routing_probe()
--
commit 83d5a1cc3383fe8d00d38b5b09449db5bf27546d
Author: Tang Bin <tangbin@cmss.chinamobile.com>
ASoC: qdsp6: q6routing: Fix memory leak on probe failure
This commit replaces kzalloc_obj() in q6pcm_routing_probe() with
devm_kzalloc_obj() and removes the manual kfree() in q6pcm_routing_remove()
to prevent leaking routing_data when devm_snd_soc_register_component() fails.
> diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
> index ea511200c8d72..0a55d1f384d4d 100644
> --- a/sound/soc/qcom/qdsp6/q6routing.c
> +++ b/sound/soc/qcom/qdsp6/q6routing.c
> @@ -1220,7 +1220,7 @@ static int q6pcm_routing_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
>
> - routing_data = kzalloc_obj(*routing_data);
> + routing_data = devm_kzalloc_obj(dev, *routing_data);
[Severity: Low]
Does sound/soc/qcom/qdsp6/q6routing.c build with CONFIG_SND_SOC_QDSP6_ROUTING
enabled?
While include/linux/slab.h defines kzalloc_obj(), neither that header nor
include/linux/device/devres.h defines devm_kzalloc_obj(), causing an
undeclared identifier error at compile time (and evaluating *routing_data as
a NULL pointer dereference rather than passing it to typeof()). Should this
use devm_kzalloc(dev, sizeof(*routing_data), GFP_KERNEL) instead?
> if (!routing_data)
> return -ENOMEM;
>
> @@ -1235,7 +1235,6 @@ static int q6pcm_routing_probe(struct platform_device *pdev)
>
> static void q6pcm_routing_remove(struct platform_device *pdev)
> {
> - kfree(routing_data);
> routing_data = NULL;
> }
[Severity: Critical]
Can switching routing_data to a device-managed allocation leave the global
static routing_data pointer dangling if devm_snd_soc_register_component()
fails in q6pcm_routing_probe()?
In sound/soc/qcom/qdsp6/q6routing.c:q6pcm_routing_probe():
routing_data = devm_kzalloc_obj(dev, *routing_data);
if (!routing_data)
return -ENOMEM;
...
return devm_snd_soc_register_component(dev, &msm_soc_routing_component,
NULL, 0);
When devm_snd_soc_register_component() returns an error, the driver core
runs really_probe() -> device_unbind_cleanup() -> devres_release_all()
without invoking q6pcm_routing_remove(). That frees the devres-managed
buffer while leaving the file-scope static pointer routing_data non-NULL.
Exported callers such as q6routing_stream_open() and q6routing_stream_close()
check whether the driver is ready by testing if (!routing_data):
sound/soc/qcom/qdsp6/q6routing.c:q6routing_stream_open() {
if (!routing_data) {
pr_err("Routing driver not yet ready\n");
return -EINVAL;
}
session = &routing_data->sessions[stream_id - 1];
...
pdata = &routing_data->port_data[session->port_id];
mutex_lock(&routing_data->lock);
}
With routing_data still non-NULL after a failed probe, subsequent calls to
q6routing_stream_open() or q6routing_stream_close() bypass the NULL check
and dereference freed slab memory, including calling mutex_lock() on
routing_data->lock.
Should q6pcm_routing_probe() only publish routing_data after
devm_snd_soc_register_component() succeeds (or clear routing_data = NULL on
failure)?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028015732.1985-1-tangbin@cmss.chinamobile.com?part=1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2] ASoC: qdsp6: q6routing: Fix memory leak on probe failure
2026-10-28 1:57 ` [PATCH v2] " Tang Bin
2026-10-28 2:10 ` sashiko-bot
@ 2026-10-28 10:25 ` Srinivas Kandagatla
1 sibling, 0 replies; 5+ messages in thread
From: Srinivas Kandagatla @ 2026-10-28 10:25 UTC (permalink / raw)
To: Tang Bin, Srinivas Kandagatla, srini, lgirdwood, broonie, perex,
tiwai
Cc: linux-sound, linux-arm-msm, linux-kernel
On 10/28/26 1:57 AM, Tang Bin wrote:
> routing_data is allocated with kzalloc() and stored in a global static
> pointer. If devm_snd_soc_register_component() fails, the probe function
> returns directly without freeing routing_data. Since the remove callback
> is not invoked on probe failure, this leads to a memory leak. On a probe
> retry, a new routing_data overwrites the global pointer, permanently
> losing the previous allocation.
>
> Fix this by switching to devm_kzalloc_obj() for the allocation. This
> ensures the memory is automatically freed by the device core if probe
> fails or when the driver is unbound. Consequently, the manual kfree()
> in the remove callback is no longer needed and must be removed to avoid
> a double-free.
>
> Fixes: e3a33673e845 ("ASoC: qdsp6: q6routing: Add q6routing driver")
> Signed-off-by: Tang Bin <tangbin@cmss.chinamobile.com>
> ---
lgtm,
Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
--Srini
> Changes in v2:
> - Use devm_kzalloc_obj() to let the device core manage the memory
> lifecycle, as suggested by Srinivas Kandagatla. This eliminates the
> need for manual error handling and prevents a double-free in remove.
>
> sound/soc/qcom/qdsp6/q6routing.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
> index d076c99f1..4816d4b9a 100644
> --- a/sound/soc/qcom/qdsp6/q6routing.c
> +++ b/sound/soc/qcom/qdsp6/q6routing.c
> @@ -1209,7 +1209,7 @@ static int q6pcm_routing_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
>
> - routing_data = kzalloc_obj(*routing_data);
> + routing_data = devm_kzalloc_obj(dev, *routing_data);
> if (!routing_data)
> return -ENOMEM;
>
> @@ -1224,7 +1224,6 @@ static int q6pcm_routing_probe(struct platform_device *pdev)
>
> static void q6pcm_routing_remove(struct platform_device *pdev)
> {
> - kfree(routing_data);
> routing_data = NULL;
> }
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-10-28 10:25 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-25 8:02 [PATCH] ASoC: qdsp6: q6routing: Fix memory leak on probe failure Tang Bin
2026-10-27 14:44 ` Srinivas Kandagatla
2026-10-28 1:57 ` [PATCH v2] " Tang Bin
2026-10-28 2:10 ` sashiko-bot
2026-10-28 10:25 ` Srinivas Kandagatla
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.