[alsa-devel] [PATCH 0/2] ASoC: topology: Fix memory leaks with ABI version mismatch
The topology loader in soc-topology.c is currently accepting ABI version mismatches for some topology components in order to keep backwards compatibility with ABIv4. When dealing with these ABI mismatch situations, temporary copies of the v4 objects are allocated and passed on to the right driver topology handlers. After that they're supposed to be freed.
However, memory leaks are currently possible in soc_tplg_link_elems_load() and also soc_tplg_manifest_load().
These patches fix these.
I've originally created a PR on github for SOF at: https://github.com/thesofproject/linux/pull/1771 as my impression was this can affect older SOF toplogies.
But as it turns out this may impact Skylake instead.
Dragos Tarcatu (2): ASoC: topology: Fix memleak in soc_tplg_link_elems_load() ASoC: topology: Fix memleak in soc_tplg_manifest_load()
sound/soc/soc-topology.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
If soc_tplg_link_config() fails, _link needs to be freed in case of topology ABI version mismatch. However the current code is returning directly and ends up leaking memory in this case. This patch fixes that.
Fixes: 593d9e52f9bb ("ASoC: topology: Add support to configure existing physical DAI links") Signed-off-by: Dragos Tarcatu dragos_tarcatu@mentor.com --- sound/soc/soc-topology.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index d2ee6ad20e83..69069f70e745 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -2377,8 +2377,11 @@ static int soc_tplg_link_elems_load(struct soc_tplg *tplg, }
ret = soc_tplg_link_config(tplg, _link); - if (ret < 0) + if (ret < 0) { + if (!abi_match) + kfree(_link); return ret; + }
/* offset by version-specific struct size and * real priv data size
The patch
ASoC: topology: Fix memleak in soc_tplg_link_elems_load()
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
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
From 2b2d5c4db732c027a14987cfccf767dac1b45170 Mon Sep 17 00:00:00 2001
From: Dragos Tarcatu dragos_tarcatu@mentor.com Date: Fri, 7 Feb 2020 20:53:24 +0200 Subject: [PATCH] ASoC: topology: Fix memleak in soc_tplg_link_elems_load()
If soc_tplg_link_config() fails, _link needs to be freed in case of topology ABI version mismatch. However the current code is returning directly and ends up leaking memory in this case. This patch fixes that.
Fixes: 593d9e52f9bb ("ASoC: topology: Add support to configure existing physical DAI links") Signed-off-by: Dragos Tarcatu dragos_tarcatu@mentor.com Link: https://lore.kernel.org/r/20200207185325.22320-2-dragos_tarcatu@mentor.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/soc-topology.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 107ba3ed5440..953517a73298 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -2376,8 +2376,11 @@ static int soc_tplg_link_elems_load(struct soc_tplg *tplg, }
ret = soc_tplg_link_config(tplg, _link); - if (ret < 0) + if (ret < 0) { + if (!abi_match) + kfree(_link); return ret; + }
/* offset by version-specific struct size and * real priv data size
In case of ABI version mismatch, _manifest needs to be freed as it is just a copy of the original topology manifest. However, if a driver manifest handler is defined, that would get executed and the cleanup is never reached. Fix that by getting the return status of manifest() instead of returning directly.
Fixes: 583958fa2e52 ("ASoC: topology: Make manifest backward compatible from ABI v4") Signed-off-by: Dragos Tarcatu dragos_tarcatu@mentor.com --- sound/soc/soc-topology.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 69069f70e745..575da6aba807 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -2545,7 +2545,7 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg, { struct snd_soc_tplg_manifest *manifest, *_manifest; bool abi_match; - int err; + int ret = 0;
if (tplg->pass != SOC_TPLG_PASS_MANIFEST) return 0; @@ -2558,19 +2558,19 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg, _manifest = manifest; } else { abi_match = false; - err = manifest_new_ver(tplg, manifest, &_manifest); - if (err < 0) - return err; + ret = manifest_new_ver(tplg, manifest, &_manifest); + if (ret < 0) + return ret; }
/* pass control to component driver for optional further init */ if (tplg->comp && tplg->ops && tplg->ops->manifest) - return tplg->ops->manifest(tplg->comp, tplg->index, _manifest); + ret = tplg->ops->manifest(tplg->comp, tplg->index, _manifest);
if (!abi_match) /* free the duplicated one */ kfree(_manifest);
- return 0; + return ret; }
/* validate header magic, size and type */
The patch
ASoC: topology: Fix memleak in soc_tplg_manifest_load()
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
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
From 242c46c023610dbc0213fc8fb6b71eb836bc5d95 Mon Sep 17 00:00:00 2001
From: Dragos Tarcatu dragos_tarcatu@mentor.com Date: Fri, 7 Feb 2020 20:53:25 +0200 Subject: [PATCH] ASoC: topology: Fix memleak in soc_tplg_manifest_load()
In case of ABI version mismatch, _manifest needs to be freed as it is just a copy of the original topology manifest. However, if a driver manifest handler is defined, that would get executed and the cleanup is never reached. Fix that by getting the return status of manifest() instead of returning directly.
Fixes: 583958fa2e52 ("ASoC: topology: Make manifest backward compatible from ABI v4") Signed-off-by: Dragos Tarcatu dragos_tarcatu@mentor.com Link: https://lore.kernel.org/r/20200207185325.22320-3-dragos_tarcatu@mentor.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/soc-topology.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 953517a73298..22c38df40d5a 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -2544,7 +2544,7 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg, { struct snd_soc_tplg_manifest *manifest, *_manifest; bool abi_match; - int err; + int ret = 0;
if (tplg->pass != SOC_TPLG_PASS_MANIFEST) return 0; @@ -2557,19 +2557,19 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg, _manifest = manifest; } else { abi_match = false; - err = manifest_new_ver(tplg, manifest, &_manifest); - if (err < 0) - return err; + ret = manifest_new_ver(tplg, manifest, &_manifest); + if (ret < 0) + return ret; }
/* pass control to component driver for optional further init */ if (tplg->comp && tplg->ops && tplg->ops->manifest) - return tplg->ops->manifest(tplg->comp, tplg->index, _manifest); + ret = tplg->ops->manifest(tplg->comp, tplg->index, _manifest);
if (!abi_match) /* free the duplicated one */ kfree(_manifest);
- return 0; + return ret; }
/* validate header magic, size and type */
participants (2)
-
Dragos Tarcatu
-
Mark Brown