OSDN Git Service

ASoC: ops: Check for negative values before reading them
authorMark Brown <broonie@kernel.org>
Fri, 28 Jan 2022 19:24:43 +0000 (19:24 +0000)
committerMark Brown <broonie@kernel.org>
Fri, 28 Jan 2022 20:55:39 +0000 (20:55 +0000)
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>
sound/soc/soc-ops.c

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