Commit 51587cd9 authored by Pierre-Louis Bossart's avatar Pierre-Louis Bossart Committed by Xiaomeng Zhang
Browse files

ASoC: SOF: topology: dynamically allocate and store DAI widget->private

mainline inclusion
from mainline-v6.9-rc1
commit 743eb6c68d3534e01e73d316ddcaa7334c0e29d3
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBWVJF
CVE: CVE-2025-21870

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=743eb6c68d3534e01e73d316ddcaa7334c0e29d3



--------------------------------

For dspless mode, we need to allocate and store an 'sdai'
structure. The existing code allocate the data on the stack and does
not set the widget->private pointer.

This minor change should not have any impact on existing DAIs, even
when the DSP is used.

Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarPéter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: default avatarBard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://msgid.link/r/20240213101247.28887-10-peter.ujfalusi@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Signed-off-by: default avatarXiaomeng Zhang <zhangxiaomeng13@huawei.com>
parent f902feb0
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -47,7 +47,6 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
{
	const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
	struct snd_sof_pipeline *spipe = swidget->spipe;
	struct snd_sof_widget *pipe_widget;
	int err = 0;
	int ret;

@@ -60,8 +59,6 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
	if (--swidget->use_count)
		return 0;

	pipe_widget = swidget->spipe->pipe_widget;

	/* reset route setup status for all routes that contain this widget */
	sof_reset_route_setup_status(sdev, swidget);

@@ -110,8 +107,9 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
	 * free the scheduler widget (same as pipe_widget) associated with the current swidget.
	 * skip for static pipelines
	 */
	if (swidget->dynamic_pipeline_widget && swidget->id != snd_soc_dapm_scheduler) {
		ret = sof_widget_free_unlocked(sdev, pipe_widget);
	if (swidget->spipe && swidget->dynamic_pipeline_widget &&
	    swidget->id != snd_soc_dapm_scheduler) {
		ret = sof_widget_free_unlocked(sdev, swidget->spipe->pipe_widget);
		if (ret < 0 && !err)
			err = ret;
	}
+10 −3
Original line number Diff line number Diff line
@@ -2347,23 +2347,29 @@ static int sof_dspless_widget_ready(struct snd_soc_component *scomp, int index,
	if (WIDGET_IS_DAI(w->id)) {
		struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
		struct snd_sof_widget *swidget;
		struct snd_sof_dai dai;
		struct snd_sof_dai *sdai;
		int ret;

		swidget = kzalloc(sizeof(*swidget), GFP_KERNEL);
		if (!swidget)
			return -ENOMEM;

		memset(&dai, 0, sizeof(dai));
		sdai = kzalloc(sizeof(*sdai), GFP_KERNEL);
		if (!sdai) {
			kfree(swidget);
			return -ENOMEM;
		}

		ret = sof_connect_dai_widget(scomp, w, tw, &dai);
		ret = sof_connect_dai_widget(scomp, w, tw, sdai);
		if (ret) {
			kfree(swidget);
			kfree(sdai);
			return ret;
		}

		swidget->scomp = scomp;
		swidget->widget = w;
		swidget->private = sdai;
		mutex_init(&swidget->setup_mutex);
		w->dobj.private = swidget;
		list_add(&swidget->list, &sdev->widget_list);
@@ -2387,6 +2393,7 @@ static int sof_dspless_widget_unload(struct snd_soc_component *scomp,

		/* remove and free swidget object */
		list_del(&swidget->list);
		kfree(swidget->private);
		kfree(swidget);
	}