From: Cezary Rojewski cezary.rojewski@intel.com
[ Upstream commit 4dee5c1cc439b0d5ef87f741518268ad6a95b23d ]
By sharing 'name' directly, tearing down components may lead to use-after-free errors. Duplicate the name to avoid that.
At the same time, update the order of operations - since commit cee28113db17 ("ASoC: dmaengine_pcm: Allow passing component name via config") the framework does not override component->name if set before invoking the initializer.
Reviewed-by: Amadeusz Sławiński amadeuszx.slawinski@linux.intel.com Signed-off-by: Cezary Rojewski cezary.rojewski@intel.com Link: https://patch.msgid.link/20250818104126.526442-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES
Rationale - Fixes a real bug (use-after-free) by eliminating shared ownership of the component name. The new code duplicates the string so each component owns its copy: `acomp->base.name = devm_kstrdup(dev, name, GFP_KERNEL);` in `sound/soc/intel/avs/pcm.c`. This prevents dangling references when one component tears down while another still references the shared pointer. - Correctly updates initialization order to align with current ASoC core behavior: the name is set before `snd_soc_component_initialize(&acomp->base, drv, dev);`. Since commit cee28113db17 (“ASoC: dmaengine_pcm: Allow passing component name via config”), the core respects a pre-set `component->name` instead of overwriting it. Upstream change in sound core (sound/soc/soc-core.c) made `snd_soc_component_initialize()` only allocate a name if `component->name` is NULL, ensuring the driver-provided name persists. - Removes the old post-init override `acomp->base.name = name;`, which was both unsafe (shared pointer) and no longer needed given the core’s updated semantics. - Minimal and localized change: affects only Intel AVS registration path (`avs_soc_component_register()` in `sound/soc/intel/avs/pcm.c`), not runtime PCM/DMA paths, scheduling, or broader ASoC architecture. Regression risk is low. - User impact: prevents crashes/corruption during component teardown/unbind or when multiple components shared the same `name` source. This is a classic stable-worthy bug fix (memory safety).
Dependencies / Backport Notes - Depends on core behavior introduced by cee28113db17 (ASoC core no longer overwrites `component->name` if set prior to initialization). For stable trees lacking that change, this patch would need adaptation: - Either keep setting the duplicated name after `snd_soc_component_initialize()` or backport the core behavior first. - Name lifetime/cleanup in the ASoC core: newer kernels that allow externally provided names must not unconditionally `kfree(component->name)` on component cleanup. Ensure your target stable tree’s `snd_soc_component_cleanup()` matches modern ownership semantics (many trees now treat `component->name` as externally provided or use safe-free patterns). If not, prefer `kstrdup()` (non- devm) here and rely on the core’s kfree to avoid double-free, or backport the corresponding core cleanup change alongside. - API drift: newer trees use the `snd_soc_add_component()`/component- init flow shown in this patch; older trees may have different signatures. If your stable branch differs, the change remains conceptually the same but needs trivial mechanical adjustment.
Summary - This is a targeted memory-safety fix with minimal scope and clear user impact. It meets stable criteria when applied to branches that have the updated ASoC core behavior (or with a small, well-understood adaptation).
sound/soc/intel/avs/pcm.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 67ce6675eea75..e738deb2d314c 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -1390,16 +1390,18 @@ int avs_soc_component_register(struct device *dev, const char *name, if (!acomp) return -ENOMEM;
- ret = snd_soc_component_initialize(&acomp->base, drv, dev); - if (ret < 0) - return ret; + acomp->base.name = devm_kstrdup(dev, name, GFP_KERNEL); + if (!acomp->base.name) + return -ENOMEM;
- /* force name change after ASoC is done with its init */ - acomp->base.name = name; INIT_LIST_HEAD(&acomp->node);
drv->use_dai_pcm_id = !obsolete_card_names;
+ ret = snd_soc_component_initialize(&acomp->base, drv, dev); + if (ret < 0) + return ret; + return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais); }