* [PATCH v2 1/3] ASoC: cs35l56: Fix missing calls to wm_adsp2_remove()
2026-06-10 9:34 [PATCH v2 0/3] ASoC: cs35l56: Fix some cleanup memory leaks Richard Fitzgerald
@ 2026-06-10 9:34 ` Richard Fitzgerald
2026-06-10 9:34 ` [PATCH v2 2/3] ASoC: cs35l56: Prevent double-free of debugfs Richard Fitzgerald
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Richard Fitzgerald @ 2026-06-10 9:34 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
Call wm_adsp2_remove() in cs35l56_remove() and the error path of
cs35l56_common_probe().
Depends on commit 7d3fb78b5503 ("ASoC: wm_adsp: Fix NULL dereference
when removing firmware controls").
The call to wm_halo_init() during driver probe should be paired with
a call to wm_adsp2_remove() but this was missing. The consequence
would be a memory leak of the control lists in the cs_dsp driver.
Fixes: e49611252900 ("ASoC: cs35l56: Add driver for Cirrus Logic CS35L56")
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
No changes in V2.
sound/soc/codecs/cs35l56.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index 0f78b1284eaa..9dcbdf8c8054 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -1997,11 +1997,14 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56)
cs35l56_dai, ARRAY_SIZE(cs35l56_dai));
if (ret < 0) {
dev_err_probe(cs35l56->base.dev, ret, "Register codec failed\n");
- goto err;
+ goto err_remove_wm_adsp;
}
return 0;
+err_remove_wm_adsp:
+ wm_adsp2_remove(&cs35l56->dsp);
+
err:
gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies);
@@ -2110,6 +2113,8 @@ void cs35l56_remove(struct cs35l56_private *cs35l56)
destroy_workqueue(cs35l56->dsp_wq);
+ wm_adsp2_remove(&cs35l56->dsp);
+
pm_runtime_dont_use_autosuspend(cs35l56->base.dev);
pm_runtime_suspend(cs35l56->base.dev);
pm_runtime_disable(cs35l56->base.dev);
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v2 2/3] ASoC: cs35l56: Prevent double-free of debugfs
2026-06-10 9:34 [PATCH v2 0/3] ASoC: cs35l56: Fix some cleanup memory leaks Richard Fitzgerald
2026-06-10 9:34 ` [PATCH v2 1/3] ASoC: cs35l56: Fix missing calls to wm_adsp2_remove() Richard Fitzgerald
@ 2026-06-10 9:34 ` Richard Fitzgerald
2026-06-10 9:34 ` [PATCH v2 3/3] ASoC: cs35l56: Cleanup if component_probe fails Richard Fitzgerald
2026-06-10 10:24 ` [PATCH v2 0/3] ASoC: cs35l56: Fix some cleanup memory leaks Mark Brown
3 siblings, 0 replies; 5+ messages in thread
From: Richard Fitzgerald @ 2026-06-10 9:34 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
Invalidate the debugfs pointer after debugfs_remove_recursive() in
cs35l56_remove_cal_debugfs(). This prevents a double-free situation when
a future commit adds proper failure cleanup in cs35l56_component_probe().
As described by Sashiko (including the future cs35l56_component_probe()
cleanup commit):
During a normal component unbind, cs35l56_component_remove() calls
cs35l56_remove_cal_debugfs() which removes the directory but leaves
a dangling pointer.
If the component is later bound again, but _cs35l56_component_probe()
fails early (for example, if the init_completion times out), this new
error path will call cs35l56_component_remove(). This causes
cs35l56_remove_cal_debugfs() to be called again with the dangling
cs35l56_base->debugfs pointer from the previous lifecycle, resulting in
a use-after-free in debugfs_remove_recursive().
Fixes: f7097161e94c ("ASoC: cs35l56: Add common code for factory calibration")
Reported-by: sashiko <sashiko@sashiko.dev>
Link: https://sashiko.dev/#/patchset/20260609120738.284770-1-rf%40opensource.cirrus.com
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
This patch is new in V2 series.
sound/soc/codecs/cs35l56-shared.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c
index 8e3538e28fad..90e52a678e71 100644
--- a/sound/soc/codecs/cs35l56-shared.c
+++ b/sound/soc/codecs/cs35l56-shared.c
@@ -1293,6 +1293,7 @@ EXPORT_SYMBOL_NS_GPL(cs35l56_create_cal_debugfs, "SND_SOC_CS35L56_SHARED");
void cs35l56_remove_cal_debugfs(struct cs35l56_base *cs35l56_base)
{
debugfs_remove_recursive(cs35l56_base->debugfs);
+ cs35l56_base->debugfs = ERR_PTR(-ENOENT);
}
EXPORT_SYMBOL_NS_GPL(cs35l56_remove_cal_debugfs, "SND_SOC_CS35L56_SHARED");
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v2 3/3] ASoC: cs35l56: Cleanup if component_probe fails
2026-06-10 9:34 [PATCH v2 0/3] ASoC: cs35l56: Fix some cleanup memory leaks Richard Fitzgerald
2026-06-10 9:34 ` [PATCH v2 1/3] ASoC: cs35l56: Fix missing calls to wm_adsp2_remove() Richard Fitzgerald
2026-06-10 9:34 ` [PATCH v2 2/3] ASoC: cs35l56: Prevent double-free of debugfs Richard Fitzgerald
@ 2026-06-10 9:34 ` Richard Fitzgerald
2026-06-10 10:24 ` [PATCH v2 0/3] ASoC: cs35l56: Fix some cleanup memory leaks Mark Brown
3 siblings, 0 replies; 5+ messages in thread
From: Richard Fitzgerald @ 2026-06-10 9:34 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
If cs35l56_component_probe() fails, call cs35l56_component_remove() to
clean up.
All the cleanup in cs35l56_component_remove() is the same cleanup that
would need to be done (at least partially) if cs35l56_component_probe()
fails. So calling cs35l56_component_remove() avoids convoluted cleanup
gotos and duplicated code in cs35l56_component_probe().
The only action in cs35l56_component_remove() that is nominally
dependent on having completed the component_probe() action is the call
to wm_adsp2_component_remove(). Though it is currently safe to call that
even if wm_adsp2_component_probe() was not called. However,
wm_adsp2_component_probe() has been trivially updated to check itself
whether it needs to cleanup.
Fixes: e49611252900 ("ASoC: cs35l56: Add driver for Cirrus Logic CS35L56")
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
No changes in V2
(Note: this was patch#2 in V1 series)
sound/soc/codecs/cs35l56.c | 13 ++++++++++++-
sound/soc/codecs/wm_adsp.c | 7 +++++++
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index 9dcbdf8c8054..2e3b5f5e33ba 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -1359,7 +1359,7 @@ VISIBLE_IF_KUNIT int cs35l56_set_fw_name(struct snd_soc_component *component)
}
EXPORT_SYMBOL_IF_KUNIT(cs35l56_set_fw_name);
-static int cs35l56_component_probe(struct snd_soc_component *component)
+static int _cs35l56_component_probe(struct snd_soc_component *component)
{
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
@@ -1459,6 +1459,17 @@ static void cs35l56_component_remove(struct snd_soc_component *component)
cs35l56->component = NULL;
}
+static int cs35l56_component_probe(struct snd_soc_component *component)
+{
+ int ret;
+
+ ret = _cs35l56_component_probe(component);
+ if (ret < 0)
+ cs35l56_component_remove(component);
+
+ return ret;
+}
+
static int cs35l56_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level)
{
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index ca630c9948e4..baa75e7ff53b 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -1170,7 +1170,14 @@ EXPORT_SYMBOL_GPL(wm_adsp2_component_probe);
int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component)
{
+ if (!dsp)
+ return 0;
+
+ if (!dsp->component)
+ return 0;
+
cs_dsp_cleanup_debugfs(&dsp->cs_dsp);
+ dsp->component = NULL;
return 0;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v2 0/3] ASoC: cs35l56: Fix some cleanup memory leaks
2026-06-10 9:34 [PATCH v2 0/3] ASoC: cs35l56: Fix some cleanup memory leaks Richard Fitzgerald
` (2 preceding siblings ...)
2026-06-10 9:34 ` [PATCH v2 3/3] ASoC: cs35l56: Cleanup if component_probe fails Richard Fitzgerald
@ 2026-06-10 10:24 ` Mark Brown
3 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2026-06-10 10:24 UTC (permalink / raw)
To: Richard Fitzgerald; +Cc: linux-sound, linux-kernel, patches
On Wed, 10 Jun 2026 10:34:29 +0100, Richard Fitzgerald wrote:
> ASoC: cs35l56: Fix some cleanup memory leaks
>
> These are for-next.
>
> They are not urgent because it only leaks memory if the driver failed to
> component_probe or is removed, which wouldn't happen in normal use.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-7.2
Thanks!
[1/3] ASoC: cs35l56: Fix missing calls to wm_adsp2_remove()
https://git.kernel.org/broonie/sound/c/85f7bf03632b
[2/3] ASoC: cs35l56: Prevent double-free of debugfs
https://git.kernel.org/broonie/sound/c/344a12ca7ba6
[3/3] ASoC: cs35l56: Cleanup if component_probe fails
https://git.kernel.org/broonie/sound/c/a0df7522dfb0
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 5+ messages in thread