[alsa-devel] [ALSA hda_codec 1/1] NULL pointer deference fixes for slave_dig_outs

robbat2 at gentoo.org robbat2 at gentoo.org
Sat Sep 13 13:18:46 CEST 2008


From: Robin H. Johnson <robbat2 at gentoo.org>

The new multiple digital output code forgot to check the slave_dig_outs for
NULL in several places. This manifests as an OOPS when changing volume amongst
other things.

Signed-off-by: Robin H. Johnson <robbat2 at gentoo.org>

diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 696d77e..b22061b 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1462,14 +1462,15 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
 					  AC_VERB_SET_DIGI_CONVERT_2,
 					  val >> 8);
 
-		for (d = codec->slave_dig_outs; *d; d++) {
-			snd_hda_codec_write_cache(codec, *d, 0,
-					  AC_VERB_SET_DIGI_CONVERT_1,
-					  val & 0xff);
-			snd_hda_codec_write_cache(codec, *d, 0,
-					  AC_VERB_SET_DIGI_CONVERT_2,
-					  val >> 8);
-		}
+		if (codec->slave_dig_outs)
+			for (d = codec->slave_dig_outs; *d; d++) {
+				snd_hda_codec_write_cache(codec, *d, 0,
+						  AC_VERB_SET_DIGI_CONVERT_1,
+						  val & 0xff);
+				snd_hda_codec_write_cache(codec, *d, 0,
+						  AC_VERB_SET_DIGI_CONVERT_2,
+						  val >> 8);
+			}
 	}
 
 	mutex_unlock(&codec->spdif_mutex);
@@ -1507,10 +1508,12 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
 					  AC_VERB_SET_DIGI_CONVERT_1,
 					  val & 0xff);
 
-		for (d = codec->slave_dig_outs; *d; d++)
-			snd_hda_codec_write_cache(codec, *d, 0,
-					  AC_VERB_SET_DIGI_CONVERT_1,
-					  val & 0xff);
+		if (codec->slave_dig_outs)
+			for (d = codec->slave_dig_outs; *d; d++)
+				snd_hda_codec_write_cache(codec, *d, 0,
+						  AC_VERB_SET_DIGI_CONVERT_1,
+						  val & 0xff);
+
 		/* unmute amp switch (if any) */
 		if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
 		    (val & AC_DIG1_ENABLE))
@@ -1664,9 +1667,10 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
 		snd_hda_codec_write_cache(codec, nid, 0,
 					  AC_VERB_SET_DIGI_CONVERT_1, val);
 
-		for (d = codec->slave_dig_outs; *d; d++)
-			snd_hda_codec_write_cache(codec, *d, 0,
-					  AC_VERB_SET_DIGI_CONVERT_1, val);
+		if (codec->slave_dig_outs)
+			for (d = codec->slave_dig_outs; *d; d++)
+				snd_hda_codec_write_cache(codec, *d, 0,
+						  AC_VERB_SET_DIGI_CONVERT_1, val);
 	}
 	mutex_unlock(&codec->spdif_mutex);
 	return change;
@@ -2617,10 +2621,11 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
 			    codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
 
-		for (d = codec->slave_dig_outs; *d; d++)
-			snd_hda_codec_write(codec, *d, 0,
-					AC_VERB_SET_DIGI_CONVERT_1,
-				    codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
+		if (codec->slave_dig_outs)
+			for (d = codec->slave_dig_outs; *d; d++)
+				snd_hda_codec_write(codec, *d, 0,
+						AC_VERB_SET_DIGI_CONVERT_1,
+					    codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
 	}
 	snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
 	/* turn on again (if needed) */
@@ -2628,10 +2633,11 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
 				    codec->spdif_ctls & 0xff);
 
-		for (d = codec->slave_dig_outs; *d; d++)
-			snd_hda_codec_write(codec, *d, 0,
-					AC_VERB_SET_DIGI_CONVERT_1,
-				    codec->spdif_ctls & 0xff);
+		if (codec->slave_dig_outs)
+			for (d = codec->slave_dig_outs; *d; d++)
+				snd_hda_codec_write(codec, *d, 0,
+						AC_VERB_SET_DIGI_CONVERT_1,
+					    codec->spdif_ctls & 0xff);
 	}
 
 }
-- 
1.6.0.1



More information about the Alsa-devel mailing list