From: Takashi Iwai Date: Thu, 15 Nov 2007 14:56:07 +0000 (+0100) Subject: [ALSA] ice1724 - Check value ranges in ctl callbacks X-Git-Tag: v2.6.25-rc1~1127^2~248 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9cd17cd2409ddbe9853575569cfd97561fa86b14;p=linux-2.6 [ALSA] ice1724 - Check value ranges in ctl callbacks Check the value ranges in ctl put callbacks properly. Also fixed the wrong access type to enum elements in aureon.c. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index ec0699c899..f83ec2f565 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -205,7 +205,7 @@ static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = ice->spec.aureon.pca9554_out; + ucontrol->value.enumerated.item[0] = ice->spec.aureon.pca9554_out; return 0; } @@ -216,10 +216,11 @@ static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol, unsigned char oval, nval; int change; + nval = ucontrol->value.enumerated.item[0]; + if (nval >= 3) + return -EINVAL; snd_ice1712_save_gpio_status(ice); - oval = ice->spec.aureon.pca9554_out; - nval = ucontrol->value.integer.value[0]; if ((change = (oval != nval))) { aureon_pca9554_write(ice, PCA9554_OUT, nval); ice->spec.aureon.pca9554_out = nval; @@ -757,10 +758,13 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ snd_ice1712_save_gpio_status(ice); for (ch = 0; ch < 2; ch++) { - if (ucontrol->value.integer.value[ch] != ice->spec.aureon.master[ch]) { + unsigned int vol = ucontrol->value.integer.value[ch]; + if (vol > WM_VOL_MAX) + continue; + vol |= ice->spec.aureon.master[ch] & WM_VOL_MUTE; + if (vol != ice->spec.aureon.master[ch]) { int dac; - ice->spec.aureon.master[ch] &= WM_VOL_MUTE; - ice->spec.aureon.master[ch] |= ucontrol->value.integer.value[ch]; + ice->spec.aureon.master[ch] = vol; for (dac = 0; dac < ice->num_total_dacs; dac += 2) wm_set_vol(ice, WM_DAC_ATTEN + dac + ch, ice->spec.aureon.vol[dac + ch], @@ -807,10 +811,13 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value * ofs = kcontrol->private_value & 0xff; snd_ice1712_save_gpio_status(ice); for (i = 0; i < voices; i++) { - idx = WM_DAC_ATTEN + ofs + i; - if (ucontrol->value.integer.value[i] != ice->spec.aureon.vol[ofs+i]) { - ice->spec.aureon.vol[ofs+i] &= WM_VOL_MUTE; - ice->spec.aureon.vol[ofs+i] |= ucontrol->value.integer.value[i]; + unsigned int vol = ucontrol->value.integer.value[i]; + if (vol > 0x7f) + continue; + vol |= ice->spec.aureon.vol[ofs+i]; + if (vol != ice->spec.aureon.vol[ofs+i]) { + ice->spec.aureon.vol[ofs+i] = vol; + idx = WM_DAC_ATTEN + ofs + i; wm_set_vol(ice, idx, ice->spec.aureon.vol[ofs+i], ice->spec.aureon.master[i]); change = 1; @@ -940,8 +947,10 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val unsigned short ovol, nvol; int change = 0; - snd_ice1712_save_gpio_status(ice); nvol = ucontrol->value.integer.value[0]; + if (nvol > PCM_RES) + return -EINVAL; + snd_ice1712_save_gpio_status(ice); nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff; ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; if (ovol != nvol) { @@ -1031,7 +1040,7 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val snd_ice1712_save_gpio_status(ice); for (i = 0; i < 2; i++) { idx = WM_ADC_GAIN + i; - nvol = ucontrol->value.integer.value[i]; + nvol = ucontrol->value.integer.value[i] & 0x1f; ovol = wm_get(ice, idx); if ((ovol & 0x1f) != nvol) { wm_put(ice, idx, nvol | (ovol & ~0x1f)); diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 3ac25058bb..c81efc2f8c 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -326,10 +326,13 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ snd_ice1712_save_gpio_status(ice); for (ch = 0; ch < 2; ch++) { - if (ucontrol->value.integer.value[ch] != ice->spec.phase28.master[ch]) { + unsigned int vol = ucontrol->value.integer.value[ch]; + if (vol > WM_VOL_MAX) + continue; + vol |= ice->spec.phase28.master[ch] & WM_VOL_MUTE; + if (vol != ice->spec.phase28.master[ch]) { int dac; - ice->spec.phase28.master[ch] &= WM_VOL_MUTE; - ice->spec.phase28.master[ch] |= ucontrol->value.integer.value[ch]; + ice->spec.phase28.master[ch] = vol; for (dac = 0; dac < ice->num_total_dacs; dac += 2) wm_set_vol(ice, WM_DAC_ATTEN + dac + ch, ice->spec.phase28.vol[dac + ch], @@ -462,10 +465,14 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value * ofs = kcontrol->private_value & 0xff; snd_ice1712_save_gpio_status(ice); for (i = 0; i < voices; i++) { - idx = WM_DAC_ATTEN + ofs + i; - if (ucontrol->value.integer.value[i] != ice->spec.phase28.vol[ofs+i]) { - ice->spec.phase28.vol[ofs+i] &= WM_VOL_MUTE; - ice->spec.phase28.vol[ofs+i] |= ucontrol->value.integer.value[i]; + unsigned int vol; + vol = ucontrol->value.integer.value[i]; + if (vol > 0x7f) + continue; + vol |= ice->spec.phase28.vol[ofs+i] & WM_VOL_MUTE; + if (vol != ice->spec.phase28.vol[ofs+i]) { + ice->spec.phase28.vol[ofs+i] = vol; + idx = WM_DAC_ATTEN + ofs + i; wm_set_vol(ice, idx, ice->spec.phase28.vol[ofs+i], ice->spec.phase28.master[i]); change = 1; @@ -595,8 +602,10 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val unsigned short ovol, nvol; int change = 0; - snd_ice1712_save_gpio_status(ice); nvol = ucontrol->value.integer.value[0]; + if (nvol > PCM_RES) + return -EINVAL; + snd_ice1712_save_gpio_status(ice); nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff; ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; if (ovol != nvol) { diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index 4180f9739e..4b21d5c1c4 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c @@ -241,7 +241,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el for (i = 0; i < 2; ++i) { reg = STAC946X_MIC_L_VOLUME + i; - nvol = ucontrol->value.integer.value[i]; + nvol = ucontrol->value.integer.value[i] & 0x0f; ovol = 0x0f - stac9460_get(ice, reg); change = ((ovol & 0x0f) != nvol); if (change) diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c index 7fcce0a506..41a153d30c 100644 --- a/sound/pci/ice1712/wtm.c +++ b/sound/pci/ice1712/wtm.c @@ -178,7 +178,7 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, if (kcontrol->private_value) { idx = STAC946X_MASTER_VOLUME; - nvol = ucontrol->value.integer.value[0]; + nvol = ucontrol->value.integer.value[0] & 0x7f; tmp = stac9460_get(ice, idx); ovol = 0x7f - (tmp & 0x7f); change = (ovol != nvol); @@ -189,7 +189,7 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, } else { id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); idx = id + STAC946X_LF_VOLUME; - nvol = ucontrol->value.integer.value[0]; + nvol = ucontrol->value.integer.value[0] & 0x7f; if (id < 6) tmp = stac9460_get(ice, idx); else @@ -317,7 +317,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, if (id == 0) { for (i = 0; i < 2; ++i) { reg = STAC946X_MIC_L_VOLUME + i; - nvol = ucontrol->value.integer.value[i]; + nvol = ucontrol->value.integer.value[i] & 0x0f; ovol = 0x0f - stac9460_get(ice, reg); change = ((ovol & 0x0f) != nvol); if (change) @@ -327,7 +327,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, } else { for (i = 0; i < 2; ++i) { reg = STAC946X_MIC_L_VOLUME + i; - nvol = ucontrol->value.integer.value[i]; + nvol = ucontrol->value.integer.value[i] & 0x0f; ovol = 0x0f - stac9460_2_get(ice, reg); change = ((ovol & 0x0f) != nvol); if (change)