]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: SOF: Intel: hda: Fix NULL pointer dereference
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Wed, 4 Feb 2026 08:18:32 +0000 (10:18 +0200)
committerMark Brown <broonie@kernel.org>
Wed, 4 Feb 2026 13:26:09 +0000 (13:26 +0000)
If there's a mismatch between the DAI links in the machine driver and
the topology, it is possible that the playback/capture widget is not
set, especially in the case of loopback capture for echo reference
where we use the dummy DAI link. Return the error when the widget is not
set to avoid a null pointer dereference like below when the topology is
broken.

RIP: 0010:hda_dai_get_ops.isra.0+0x14/0xa0 [snd_sof_intel_hda_common]

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com>
Reviewed-by: Mateusz Redzynia <mateuszx.redzynia@intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://patch.msgid.link/20260204081833.16630-10-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/intel/hda-dai.c

index 883d0d3bae9ec206dacf8d27344285eb1c3fcd15..3c742d53513337d3333ae09bb736f131bc4e49c6 100644 (file)
@@ -70,12 +70,22 @@ static const struct hda_dai_widget_dma_ops *
 hda_dai_get_ops(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai)
 {
        struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream);
-       struct snd_sof_widget *swidget = w->dobj.private;
+       struct snd_sof_widget *swidget;
        struct snd_sof_dev *sdev;
        struct snd_sof_dai *sdai;
 
-       sdev = widget_to_sdev(w);
+       /*
+        * this is unlikely if the topology and the machine driver DAI links match.
+        * But if there's a missing DAI link in topology, this will prevent a NULL pointer
+        * dereference later on.
+        */
+       if (!w) {
+               dev_err(cpu_dai->dev, "%s: widget is NULL\n", __func__);
+               return NULL;
+       }
 
+       sdev = widget_to_sdev(w);
+       swidget = w->dobj.private;
        if (!swidget) {
                dev_err(sdev->dev, "%s: swidget is NULL\n", __func__);
                return NULL;