Unverified Commit 6f0307df authored by Pierre-Louis Bossart's avatar Pierre-Louis Bossart Committed by Mark Brown
Browse files

ASoC: topology: fix kernel oops on route addition error



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: 7df04ea7 ('ASoC: topology: modify dapm route loading routine and add dapm route unloading')
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20200707203749.113883-2-pierre-louis.bossart@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 503ed522
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -1261,17 +1261,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.