diff options
author | Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> | 2020-07-07 23:37:45 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-07-29 11:20:00 +0300 |
commit | f3ad39ba80c50280d5a43327a782371adda7f927 (patch) | |
tree | 12329e07537c366d152375eafb7ab80db3705316 | |
parent | 9972321613e8213e76506abe1e53c69c250f89b1 (diff) | |
download | linux-f3ad39ba80c50280d5a43327a782371adda7f927.tar.xz |
ASoC: topology: fix kernel oops on route addition error
commit 6f0307df83f2aa6bdf656c2219c89ce96502d20e upstream.
When errors happens while loading graph components, the kernel oopses
while trying to remove all topology components. This can be
root-caused to a list pointing to memory that was already freed on
error.
remove_route() is already called on errors and will perform the
required cleanups so there's no need to free the route memory in
soc_tplg_dapm_graph_elems_load() if the route was added to the
list. We do however want to free the routes allocated but not added to
the list.
Fixes: 7df04ea7a31ea ('ASoC: topology: modify dapm route loading routine and add dapm route unloading')
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20200707203749.113883-2-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | sound/soc/soc-topology.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 6df3b0d12d87..989ed15e3693 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -1285,17 +1285,29 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg, list_add(&routes[i]->dobj.list, &tplg->comp->dobj_list); ret = soc_tplg_add_route(tplg, routes[i]); - if (ret < 0) + if (ret < 0) { + /* + * this route was added to the list, it will + * be freed in remove_route() so increment the + * counter to skip it in the error handling + * below. + */ + i++; break; + } /* add route, but keep going if some fail */ snd_soc_dapm_add_routes(dapm, routes[i], 1); } - /* free memory allocated for all dapm routes in case of error */ - if (ret < 0) - for (i = 0; i < count ; i++) - kfree(routes[i]); + /* + * free memory allocated for all dapm routes not added to the + * list in case of error + */ + if (ret < 0) { + while (i < count) + kfree(routes[i++]); + } /* * free pointer to array of dapm routes as this is no longer needed. |