Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

ASoC: dapm: fix use-after-free issue with dailink sname



Commit 7620fe91 ("ASoC: topology: fix memory leak in
soc_tplg_dapm_widget_create") fixed a memory leak issue, but
additional tests and KASAN reports show a use-after-free in soc-dapm.

The widgets are created with a kmemdup operating on a template. The
"name" string is also duplicated, but the "sname" string is not. As a
result, when the template is freed after widget creation, its sname
string is still used.

Fix by explicitly duplicating the "sname" string, and freeing it when
required.

Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4bd8597d
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -295,7 +295,22 @@ EXPORT_SYMBOL_GPL(dapm_mark_endpoints_dirty);
static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
	const struct snd_soc_dapm_widget *_widget)
{
	return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL);
	struct snd_soc_dapm_widget *w;

	w = kmemdup(_widget, sizeof(*_widget), GFP_KERNEL);
	if (!w)
		return NULL;

	/*
	 * w->name is duplicated in caller, but w->sname isn't.
	 * Duplicate it here if defined
	 */
	if (_widget->sname) {
		w->sname = kstrdup_const(_widget->sname, GFP_KERNEL);
		if (!w->sname)
			return NULL;
	}
	return w;
}

struct dapm_kcontrol_data {
@@ -2412,6 +2427,7 @@ void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w)

	kfree(w->kcontrols);
	kfree_const(w->name);
	kfree_const(w->sname);
	kfree(w);
}

@@ -3469,6 +3485,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
	else
		w->name = kstrdup_const(widget->name, GFP_KERNEL);
	if (w->name == NULL) {
		kfree_const(w->sname);
		kfree(w);
		return ERR_PTR(-ENOMEM);
	}