summary refs log tree commit diff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2007-11-15 14:42:34 +0100
committerJaroslav Kysela <perex@perex.cz>2007-11-19 18:41:30 +0100
commit5fe619f983d6c7c0a578fcaabf80edd30e7ce46c (patch)
tree58b1737a4ae7db6ba93288fd9cc1775d8945e7c0
parent7eba5c9dc3735b14e3df7366671adc15e0c8a048 (diff)
downloadlinux-5fe619f983d6c7c0a578fcaabf80edd30e7ce46c.tar.gz
[ALSA] ca0106 - Check value range in ctl callbacks
Check the value ranges in ctl put callbacks properly.
Some callbacks may access a wrong pointer depending on the value passed.
Also, fixed the access to the wrong field for enum values, and fixed
some callbacks to return the proper error code.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index be519a17dfa5..3f9b5c560036 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -86,7 +86,7 @@ static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
 {
 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 
-	ucontrol->value.enumerated.item[0] = emu->spdif_enable;
+	ucontrol->value.integer.value[0] = emu->spdif_enable;
 	return 0;
 }
 
@@ -98,11 +98,11 @@ static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
 	int change = 0;
 	u32 mask;
 
-	val = ucontrol->value.enumerated.item[0] ;
+	val = !!ucontrol->value.integer.value[0];
 	change = (emu->spdif_enable != val);
 	if (change) {
 		emu->spdif_enable = val;
-		if (val == 1) {
+		if (val) {
 			/* Digital */
 			snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
 			snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
@@ -159,6 +159,8 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
 	u32 source;
 
 	val = ucontrol->value.enumerated.item[0] ;
+	if (val >= 6)
+		return -EINVAL;
 	change = (emu->capture_source != val);
 	if (change) {
 		emu->capture_source = val;
@@ -207,6 +209,8 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
 	 * for the particular source.
 	 */
 	source_id = ucontrol->value.enumerated.item[0] ;
+	if (source_id >= 4)
+		return -EINVAL;
 	change = (emu->i2c_capture_source != source_id);
 	if (change) {
 		snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
@@ -271,6 +275,8 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
 	u32 tmp;
 
 	val = ucontrol->value.enumerated.item[0] ;
+	if (val > 1)
+		return -EINVAL;
 	change = (emu->capture_mic_line_in != val);
 	if (change) {
 		emu->capture_mic_line_in = val;
@@ -443,7 +449,7 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
 	ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
 	ngain = ucontrol->value.integer.value[0];
 	if (ngain > 0xff)
-		return 0;
+		return -EINVAL;
 	if (ogain != ngain) {
 		if (emu->i2c_capture_source == source_id)
 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
@@ -453,7 +459,7 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
 	ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
 	ngain = ucontrol->value.integer.value[1];
 	if (ngain > 0xff)
-		return 0;
+		return -EINVAL;
 	if (ogain != ngain) {
 		if (emu->i2c_capture_source == source_id)
 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
@@ -497,7 +503,7 @@ static int spi_mute_put(struct snd_kcontrol *kcontrol,
 	}
 
 	ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
-	return ret ? -1 : 1;
+	return ret ? -EINVAL : 1;
 }
 
 #define CA_VOLUME(xname,chid,reg) \