From 7db53c21b1c3c25676d1125049bc92c756421cd6 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 15 Oct 2021 18:12:52 +0200 Subject: ASoC: core: Remove invalid snd_soc_component_set_jack call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If snd_soc_component_set_jack() is called after snd_soc_component_remove() it may operate on memory which is freed in ->remove handler. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20211015161257.27052-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 94f1548b8a32..dcf6be4c4aaa 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1342,9 +1342,6 @@ static void soc_remove_component(struct snd_soc_component *component, if (probed) snd_soc_component_remove(component); - /* For framework level robustness */ - snd_soc_component_set_jack(component, NULL, NULL); - list_del_init(&component->card_list); snd_soc_dapm_free(snd_soc_component_get_dapm(component)); soc_cleanup_component_debugfs(component); -- cgit v1.2.3 From 86e2d14b6d1a68941b6c0ef39502ec1433b680cb Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 15 Oct 2021 18:12:53 +0200 Subject: ASoC: topology: Add header payload_size verification Add sanity check to make sure the data is read within file boundary. Helps in situations where file is only partially copied or malformed. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20211015161257.27052-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/soc-topology.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 7a4559ddf903..e5352cc6524f 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -2438,6 +2438,7 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg, _manifest = manifest; } else { abi_match = false; + ret = manifest_new_ver(tplg, manifest, &_manifest); if (ret < 0) return ret; @@ -2468,6 +2469,14 @@ static int soc_valid_header(struct soc_tplg *tplg, return -EINVAL; } + if (soc_tplg_get_hdr_offset(tplg) + hdr->payload_size >= tplg->fw->size) { + dev_err(tplg->dev, + "ASoC: invalid header of type %d at offset %ld payload_size %d\n", + le32_to_cpu(hdr->type), soc_tplg_get_hdr_offset(tplg), + hdr->payload_size); + return -EINVAL; + } + /* big endian firmware objects not supported atm */ if (le32_to_cpu(hdr->magic) == SOC_TPLG_MAGIC_BIG_ENDIAN) { dev_err(tplg->dev, -- cgit v1.2.3 From 2e288333e9e0a14f9895321a848992b25a0e5563 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 15 Oct 2021 18:12:54 +0200 Subject: ASoC: topology: Check for dapm widget completeness MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add sanity checks to make sure the data is read within file boundary. Helps in situations where file is only partially copied or malformed. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20211015161257.27052-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/soc-topology.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index e5352cc6524f..f03f50653eca 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -1591,11 +1591,28 @@ static int soc_tplg_dapm_widget_elems_load(struct soc_tplg *tplg, struct snd_soc_tplg_dapm_widget *widget = (struct snd_soc_tplg_dapm_widget *) tplg->pos; int ret; + /* + * check if widget itself fits within topology file + * use sizeof instead of widget->size, as we can't be sure + * it is set properly yet (file may end before it is present) + */ + if (soc_tplg_get_offset(tplg) + sizeof(*widget) >= tplg->fw->size) { + dev_err(tplg->dev, "ASoC: invalid widget data size\n"); + return -EINVAL; + } + + /* check if widget has proper size */ if (le32_to_cpu(widget->size) != sizeof(*widget)) { dev_err(tplg->dev, "ASoC: invalid widget size\n"); return -EINVAL; } + /* check if widget private data fits within topology file */ + if (soc_tplg_get_offset(tplg) + le32_to_cpu(widget->priv.size) >= tplg->fw->size) { + dev_err(tplg->dev, "ASoC: invalid widget private data size\n"); + return -EINVAL; + } + ret = soc_tplg_dapm_widget_create(tplg, widget); if (ret < 0) { dev_err(tplg->dev, "ASoC: failed to load widget %s\n", -- cgit v1.2.3 From 2a710bb35a5abfbca48ed7c229205ace472692d3 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 15 Oct 2021 18:12:55 +0200 Subject: ASoC: topology: Use correct device for prints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit soc_tplg_add_dcontrol() passes device as argument which is later used to print messages. Align it with all other prints in file to use tplg->dev. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20211015161257.27052-5-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/soc-topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index f03f50653eca..f7311429651a 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -351,7 +351,7 @@ static int soc_tplg_add_kcontrol(struct soc_tplg *tplg, struct snd_soc_component *comp = tplg->comp; return soc_tplg_add_dcontrol(comp->card->snd_card, - comp->dev, k, comp->name_prefix, comp, kcontrol); + tplg->dev, k, comp->name_prefix, comp, kcontrol); } /* remove a mixer kcontrol */ -- cgit v1.2.3 From f714fbc1e89a3533b2578e0c90ce4f5c05a57f96 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 15 Oct 2021 18:12:56 +0200 Subject: ASoC: topology: Change topology device to card device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Topology needs device for prints and resource allocation. So far, component->dev is used. However, this may lead to high memory use in model where card is an independent driver which can be reloaded and topology is loaded from component's probe() method. Every time machine driver is reloaded topology is being loaded anew, each time allocating new memory. Said memory will only be freed when component itself is being freed. Address the problem by tying topology to component->card->dev instead, so memory occupied by the topology is freed whenever related machine device gets removed. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20211015161257.27052-6-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/soc-topology.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index f7311429651a..557e22c5254c 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -2668,17 +2668,17 @@ int snd_soc_tplg_component_load(struct snd_soc_component *comp, /* * check if we have sane parameters: * comp - needs to exist to keep and reference data while parsing - * comp->dev - used for resource management and prints * comp->card - used for setting card related parameters + * comp->card->dev - used for resource management and prints * fw - we need it, as it is the very thing we parse */ - if (!comp || !comp->dev || !comp->card || !fw) + if (!comp || !comp->card || !comp->card->dev || !fw) return -EINVAL; /* setup parsing context */ memset(&tplg, 0, sizeof(tplg)); tplg.fw = fw; - tplg.dev = comp->dev; + tplg.dev = comp->card->dev; tplg.comp = comp; if (ops) { tplg.ops = ops; -- cgit v1.2.3 From 6c504663ba2ee2abeaf5622e27082819326c1bd4 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 15 Oct 2021 18:12:57 +0200 Subject: ASoC: Stop dummy from overriding hwparams MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case that there are other components assigned to runtime device, depending on order dummy component can override their params with its own, which shouldn't happen. Check if there are any other components assigned to rtd and if so, skip setting hwparams. Occurs when using topology where 'snd-soc-dummy' gets assigned by default as codec and platform component. Alternative approach would be to copy whole dummy handling and rename it to "snd-soc-null" or something similar. And remove hwparams assignment to make it really do nothing. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20211015161257.27052-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/soc-utils.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 299b5d6ebfd1..a4efe7e52a8b 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -63,10 +63,23 @@ static const struct snd_pcm_hardware dummy_dma_hardware = { .periods_max = 128, }; + +static const struct snd_soc_component_driver dummy_platform; + static int dummy_dma_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + int i; + + /* + * If there are other components associated with rtd, we shouldn't + * override their hwparams + */ + for_each_rtd_components(rtd, i, component) { + if (component->driver == &dummy_platform) + return 0; + } /* BE's dont need dummy params */ if (!rtd->dai_link->no_pcm) -- cgit v1.2.3