diff mbox series

[1/9] ASoC: SOF: Intel: hda-dai: add error checks to prevent static analysis warnings

Message ID 20230602205620.310879-2-pierre-louis.bossart@linux.intel.com (mailing list archive)
State Accepted
Commit c4be6024d51d3930459a61d4c91990f20264c60b
Headers show
Series ASoC: SOF: Intel: LunarLake preparation patches | expand

Commit Message

Pierre-Louis Bossart June 2, 2023, 8:56 p.m. UTC
make KCFLAGS='-fanalyzer' sound/soc/sof/intel/ reports several NULL
pointer dereference paths.

Example log:
ops = hda_dai_get_ops(substream, cpu_dai);
  |      |                          ^~~~~
  |      |                          |
  |      |               (14) return of NULL to ‘non_hda_dai_hw_params’ from ‘hda_dai_get_ops’
  |  353 |         sdev = widget_to_sdev(w);
  |  354 |         hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
  |      |                       ~~~~~~~~~~~~~~~~~~~~
  |      |                          |
  |      |                          (15) dereference of NULL ‘ops’

The function hda_dai_get_ops() can return NULL, but the return value
is not checked across the board. It's not a problem today, since we do
check in the first use of the function, but static analysis tools are
not aware of the different ALSA stages. Rather than argue forever,
let's just add the error checks consistently and make sure this tool
can be added to the CI checks.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
---
 sound/soc/sof/intel/hda-dai.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c
index 09d8ee98581d..3d89c1923b03 100644
--- a/sound/soc/sof/intel/hda-dai.c
+++ b/sound/soc/sof/intel/hda-dai.c
@@ -120,6 +120,11 @@  static int hda_link_dma_cleanup(struct snd_pcm_substream *substream,
 	struct snd_sof_dev *sdev;
 	int stream_tag;
 
+	if (!ops) {
+		dev_err(cpu_dai->dev, "DAI widget ops not set\n");
+		return -EINVAL;
+	}
+
 	sdev = dai_to_sdev(substream, cpu_dai);
 
 	hlink = snd_hdac_ext_bus_get_hlink_by_name(bus, codec_dai->component->name);
@@ -158,6 +163,11 @@  static int hda_link_dma_hw_params(struct snd_pcm_substream *substream,
 	unsigned int link_bps;
 	int stream_tag;
 
+	if (!ops) {
+		dev_err(cpu_dai->dev, "DAI widget ops not set\n");
+		return -EINVAL;
+	}
+
 	sdev = dai_to_sdev(substream, cpu_dai);
 	bus = sof_to_bus(sdev);
 
@@ -216,7 +226,7 @@  static int __maybe_unused hda_dai_hw_free(struct snd_pcm_substream *substream,
 	struct snd_sof_dev *sdev = dai_to_sdev(substream, cpu_dai);
 
 	if (!ops) {
-		dev_err(sdev->dev, "DAI widget ops not set\n");
+		dev_err(cpu_dai->dev, "DAI widget ops not set\n");
 		return -EINVAL;
 	}
 
@@ -274,6 +284,11 @@  static int __maybe_unused hda_dai_trigger(struct snd_pcm_substream *substream, i
 	struct snd_sof_dev *sdev;
 	int ret;
 
+	if (!ops) {
+		dev_err(dai->dev, "DAI widget ops not set\n");
+		return -EINVAL;
+	}
+
 	dev_dbg(dai->dev, "cmd=%d dai %s direction %d\n", cmd,
 		dai->name, substream->stream);