From d4079ac49a08e36d6839a9ceb26aec8c24c9ed82 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 15 Nov 2007 16:14:12 +0100 Subject: [ALSA] powermac - Check value range in ctl callbacks Check the value ranges in ctl put callbacks properly in snd-powermac driver. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/ppc/awacs.c | 20 ++++++++++++++----- sound/ppc/beep.c | 7 +++++-- sound/ppc/burgundy.c | 11 +++++++---- sound/ppc/daca.c | 17 ++++++++++------ sound/ppc/pmac.c | 2 +- sound/ppc/tumbler.c | 55 ++++++++++++++++++++++++++++++++++++++-------------- 6 files changed, 79 insertions(+), 33 deletions(-) (limited to 'sound/ppc') diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c index 05dabe45465..b15bfb6f701 100644 --- a/sound/ppc/awacs.c +++ b/sound/ppc/awacs.c @@ -175,10 +175,12 @@ static int snd_pmac_awacs_put_volume(struct snd_kcontrol *kcontrol, int inverted = (kcontrol->private_value >> 16) & 1; int val, oldval; unsigned long flags; - int vol[2]; + unsigned int vol[2]; vol[0] = ucontrol->value.integer.value[0]; vol[1] = ucontrol->value.integer.value[1]; + if (vol[0] > 0x0f || vol[1] > 0x0f) + return -EINVAL; if (inverted) { vol[0] = 0x0f - vol[0]; vol[1] = 0x0f - vol[1]; @@ -421,10 +423,14 @@ static int snd_pmac_awacs_put_tone_amp(struct snd_kcontrol *kcontrol, struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); int index = kcontrol->private_value; struct awacs_amp *amp = chip->mixer_data; + unsigned int val; snd_assert(amp, return -EINVAL); snd_assert(index >= 0 && index <= 1, return -EINVAL); - if (ucontrol->value.integer.value[0] != amp->amp_tone[index]) { - amp->amp_tone[index] = ucontrol->value.integer.value[0]; + val = ucontrol->value.integer.value[0]; + if (val > 14) + return -EINVAL; + if (val != amp->amp_tone[index]) { + amp->amp_tone[index] = val; awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]); return 1; } @@ -456,9 +462,13 @@ static int snd_pmac_awacs_put_master_amp(struct snd_kcontrol *kcontrol, { struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); struct awacs_amp *amp = chip->mixer_data; + unsigned int val; snd_assert(amp, return -EINVAL); - if (ucontrol->value.integer.value[0] != amp->amp_master) { - amp->amp_master = ucontrol->value.integer.value[0]; + val = ucontrol->value.integer.value[0]; + if (val > 99) + return -EINVAL; + if (val != amp->amp_master) { + amp->amp_master = val; awacs_amp_set_master(amp, amp->amp_master); return 1; } diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c index 566b5ab9d4e..465dd0466b9 100644 --- a/sound/ppc/beep.c +++ b/sound/ppc/beep.c @@ -195,10 +195,13 @@ static int snd_pmac_put_beep(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); - int oval; + unsigned int oval, nval; snd_assert(chip->beep, return -ENXIO); oval = chip->beep->volume; - chip->beep->volume = ucontrol->value.integer.value[0]; + nval = ucontrol->value.integer.value[0]; + if (nval > 100) + return -EINVAL; + chip->beep->volume = nval; return oval != chip->beep->volume; } diff --git a/sound/ppc/burgundy.c b/sound/ppc/burgundy.c index e02263fe44d..fec74e82974 100644 --- a/sound/ppc/burgundy.c +++ b/sound/ppc/burgundy.c @@ -136,6 +136,9 @@ snd_pmac_burgundy_write_volume(struct snd_pmac *chip, unsigned int address, { int hardvolume, lvolume, rvolume; + if (volume[0] < 0 || volume[0] > 100 || + volume[1] < 0 || volume[1] > 100) + return; /* -EINVAL */ lvolume = volume[0] ? volume[0] + BURGUNDY_VOLUME_OFFSET : 0; rvolume = volume[1] ? volume[1] + BURGUNDY_VOLUME_OFFSET : 0; @@ -301,14 +304,14 @@ static int snd_pmac_burgundy_put_volume_out(struct snd_kcontrol *kcontrol, struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff); int stereo = (kcontrol->private_value >> 24) & 1; - int oval, val; + unsigned int oval, val; oval = ~snd_pmac_burgundy_rcb(chip, addr) & 0xff; - val = ucontrol->value.integer.value[0]; + val = ucontrol->value.integer.value[0] & 15; if (stereo) - val |= ucontrol->value.integer.value[1] << 4; + val |= (ucontrol->value.integer.value[1] & 15) << 4; else - val |= ucontrol->value.integer.value[0] << 4; + val |= val << 4; val = ~val & 0xff; snd_pmac_burgundy_wcb(chip, addr, val); return val != oval; diff --git a/sound/ppc/daca.c b/sound/ppc/daca.c index c5a1f0be6a4..0c8145792d5 100644 --- a/sound/ppc/daca.c +++ b/sound/ppc/daca.c @@ -115,7 +115,7 @@ static int daca_put_deemphasis(struct snd_kcontrol *kcontrol, return -ENODEV; change = mix->deemphasis != ucontrol->value.integer.value[0]; if (change) { - mix->deemphasis = ucontrol->value.integer.value[0]; + mix->deemphasis = !!ucontrol->value.integer.value[0]; daca_set_volume(mix); } return change; @@ -149,15 +149,20 @@ static int daca_put_volume(struct snd_kcontrol *kcontrol, { struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); struct pmac_daca *mix; + unsigned int vol[2]; int change; if (! (mix = chip->mixer_data)) return -ENODEV; - change = mix->left_vol != ucontrol->value.integer.value[0] || - mix->right_vol != ucontrol->value.integer.value[1]; + vol[0] = ucontrol->value.integer.value[0]; + vol[1] = ucontrol->value.integer.value[1]; + if (vol[0] > DACA_VOL_MAX || vol[1] > DACA_VOL_MAX) + return -EINVAL; + change = mix->left_vol != vol[0] || + mix->right_vol != vol[1]; if (change) { - mix->left_vol = ucontrol->value.integer.value[0]; - mix->right_vol = ucontrol->value.integer.value[1]; + mix->left_vol = vol[0]; + mix->right_vol = vol[1]; daca_set_volume(mix); } return change; @@ -188,7 +193,7 @@ static int daca_put_amp(struct snd_kcontrol *kcontrol, return -ENODEV; change = mix->amp_on != ucontrol->value.integer.value[0]; if (change) { - mix->amp_on = ucontrol->value.integer.value[0]; + mix->amp_on = !!ucontrol->value.integer.value[0]; i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_GCFG, mix->amp_on ? 0x05 : 0x04); } diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 4f9b19c90a4..8c47bebc77c 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c @@ -1028,7 +1028,7 @@ static int pmac_auto_mute_put(struct snd_kcontrol *kcontrol, { struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); if (ucontrol->value.integer.value[0] != chip->auto_mute) { - chip->auto_mute = ucontrol->value.integer.value[0]; + chip->auto_mute = !!ucontrol->value.integer.value[0]; if (chip->update_automute) chip->update_automute(chip, 1); return 1; diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index 5821cdd0bec..bacff3d1c18 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c @@ -275,14 +275,20 @@ static int tumbler_put_master_volume(struct snd_kcontrol *kcontrol, { struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); struct pmac_tumbler *mix = chip->mixer_data; + unsigned int vol[2]; int change; snd_assert(mix, return -ENODEV); - change = mix->master_vol[0] != ucontrol->value.integer.value[0] || - mix->master_vol[1] != ucontrol->value.integer.value[1]; + vol[0] = ucontrol->value.integer.value[0]; + vol[1] = ucontrol->value.integer.value[1]; + if (vol[0] >= ARRAY_SIZE(master_volume_table) || + vol[1] >= ARRAY_SIZE(master_volume_table)) + return -EINVAL; + change = mix->master_vol[0] != vol[0] || + mix->master_vol[1] != vol[1]; if (change) { - mix->master_vol[0] = ucontrol->value.integer.value[0]; - mix->master_vol[1] = ucontrol->value.integer.value[1]; + mix->master_vol[0] = vol[0]; + mix->master_vol[1] = vol[1]; tumbler_set_master_volume(mix); } return change; @@ -417,13 +423,22 @@ static int tumbler_put_drc_value(struct snd_kcontrol *kcontrol, { struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); struct pmac_tumbler *mix; + unsigned int val; int change; if (! (mix = chip->mixer_data)) return -ENODEV; - change = mix->drc_range != ucontrol->value.integer.value[0]; + val = ucontrol->value.integer.value[0]; + if (chip->model == PMAC_TUMBLER) { + if (val > TAS3001_DRC_MAX) + return -EINVAL; + } else { + if (val > TAS3004_DRC_MAX) + return -EINVAL; + } + change = mix->drc_range != val; if (change) { - mix->drc_range = ucontrol->value.integer.value[0]; + mix->drc_range = val; if (chip->model == PMAC_TUMBLER) tumbler_set_drc(mix); else @@ -530,13 +545,17 @@ static int tumbler_put_mono(struct snd_kcontrol *kcontrol, struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value; struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); struct pmac_tumbler *mix; + unsigned int vol; int change; if (! (mix = chip->mixer_data)) return -ENODEV; - change = mix->mono_vol[info->index] != ucontrol->value.integer.value[0]; + vol = ucontrol->value.integer.value[0]; + if (vol >= info->max) + return -EINVAL; + change = mix->mono_vol[info->index] != vol; if (change) { - mix->mono_vol[info->index] = ucontrol->value.integer.value[0]; + mix->mono_vol[info->index] = vol; tumbler_set_mono_volume(mix, info); } return change; @@ -672,15 +691,21 @@ static int snapper_put_mix(struct snd_kcontrol *kcontrol, int idx = (int)kcontrol->private_value; struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); struct pmac_tumbler *mix; + unsigned int vol[2]; int change; if (! (mix = chip->mixer_data)) return -ENODEV; - change = mix->mix_vol[idx][0] != ucontrol->value.integer.value[0] || - mix->mix_vol[idx][1] != ucontrol->value.integer.value[1]; + vol[0] = ucontrol->value.integer.value[0]; + vol[1] = ucontrol->value.integer.value[1]; + if (vol[0] >= ARRAY_SIZE(mixer_volume_table) || + vol[1] >= ARRAY_SIZE(mixer_volume_table)) + return -EINVAL; + change = mix->mix_vol[idx][0] != vol[0] || + mix->mix_vol[idx][1] != vol[1]; if (change) { - mix->mix_vol[idx][0] = ucontrol->value.integer.value[0]; - mix->mix_vol[idx][1] = ucontrol->value.integer.value[1]; + mix->mix_vol[idx][0] = vol[0]; + mix->mix_vol[idx][1] = vol[1]; snapper_set_mix_vol(mix, idx); } return change; @@ -784,7 +809,7 @@ static int snapper_get_capture_source(struct snd_kcontrol *kcontrol, struct pmac_tumbler *mix = chip->mixer_data; snd_assert(mix, return -ENODEV); - ucontrol->value.integer.value[0] = mix->capture_source; + ucontrol->value.enumerated.value[0] = mix->capture_source; return 0; } @@ -796,9 +821,9 @@ static int snapper_put_capture_source(struct snd_kcontrol *kcontrol, int change; snd_assert(mix, return -ENODEV); - change = ucontrol->value.integer.value[0] != mix->capture_source; + change = ucontrol->value.enuemerated.item[0] != mix->capture_source; if (change) { - mix->capture_source = !!ucontrol->value.integer.value[0]; + mix->capture_source = !!ucontrol->value.enumerated.item[0]; snapper_set_capture_source(mix); } return change; -- cgit v1.2.3