ASoC: ops: Check for negative values before reading them

The controls allow inputs to be specified as negative but our manipulating
them into register fields need to be done on unsigned variables so the
checks for negative numbers weren't taking effect properly. Do the checks
for negative values on the variable in the ABI struct rather than on our
local unsigned copy.

Signed-off-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20220128192443.3504823-1-broonie@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Mark Brown 2022-01-28 19:24:43 +00:00
parent 4c38f8747c
commit 1601033da2
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -316,26 +316,26 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
if (sign_bit) if (sign_bit)
mask = BIT(sign_bit + 1) - 1; mask = BIT(sign_bit + 1) - 1;
if (ucontrol->value.integer.value[0] < 0)
return -EINVAL;
val = ucontrol->value.integer.value[0]; val = ucontrol->value.integer.value[0];
if (mc->platform_max && val > mc->platform_max) if (mc->platform_max && val > mc->platform_max)
return -EINVAL; return -EINVAL;
if (val > max - min) if (val > max - min)
return -EINVAL; return -EINVAL;
if (val < 0)
return -EINVAL;
val = (val + min) & mask; val = (val + min) & mask;
if (invert) if (invert)
val = max - val; val = max - val;
val_mask = mask << shift; val_mask = mask << shift;
val = val << shift; val = val << shift;
if (snd_soc_volsw_is_stereo(mc)) { if (snd_soc_volsw_is_stereo(mc)) {
if (ucontrol->value.integer.value[1] < 0)
return -EINVAL;
val2 = ucontrol->value.integer.value[1]; val2 = ucontrol->value.integer.value[1];
if (mc->platform_max && val2 > mc->platform_max) if (mc->platform_max && val2 > mc->platform_max)
return -EINVAL; return -EINVAL;
if (val2 > max - min) if (val2 > max - min)
return -EINVAL; return -EINVAL;
if (val2 < 0)
return -EINVAL;
val2 = (val2 + min) & mask; val2 = (val2 + min) & mask;
if (invert) if (invert)
val2 = max - val2; val2 = max - val2;
@ -423,13 +423,13 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
int err = 0; int err = 0;
unsigned int val, val_mask; unsigned int val, val_mask;
if (ucontrol->value.integer.value[0] < 0)
return -EINVAL;
val = ucontrol->value.integer.value[0]; val = ucontrol->value.integer.value[0];
if (mc->platform_max && val > mc->platform_max) if (mc->platform_max && val > mc->platform_max)
return -EINVAL; return -EINVAL;
if (val > max - min) if (val > max - min)
return -EINVAL; return -EINVAL;
if (val < 0)
return -EINVAL;
val_mask = mask << shift; val_mask = mask << shift;
val = (val + min) & mask; val = (val + min) & mask;
val = val << shift; val = val << shift;