]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iio: gyro: bmg160: bail out when bandwidth/filter is not in table
authorStepan Ionichev <sozdayvek@gmail.com>
Sun, 10 May 2026 02:35:00 +0000 (07:35 +0500)
committerJonathan Cameron <jic23@kernel.org>
Sat, 16 May 2026 10:44:51 +0000 (11:44 +0100)
bmg160_get_filter() walks bmg160_samp_freq_table[] looking for the entry
matching the bw_bits value read from the chip:

for (i = 0; i < ARRAY_SIZE(bmg160_samp_freq_table); ++i) {
if (bmg160_samp_freq_table[i].bw_bits == bw_bits)
break;
}
*val = bmg160_samp_freq_table[i].filter;

If no entry matches, i ends up equal to the array size and the next line
reads one slot past the end. bmg160_set_filter() has the same shape, driven
by 'val' instead of bw_bits.

smatch flags both:

  drivers/iio/gyro/bmg160_core.c:204 bmg160_get_filter() error:
  buffer overflow 'bmg160_samp_freq_table' 7 <= 7
  drivers/iio/gyro/bmg160_core.c:222 bmg160_set_filter() error:
  buffer overflow 'bmg160_samp_freq_table' 7 <= 7

Return -EINVAL when no entry matches.

The set_filter() path is reachable from userspace via the sysfs
in_anglvel_filter_low_pass_3db_frequency interface, so userspace can
trivially trigger the out-of-bounds read with a value that is not in
bmg160_samp_freq_table[].filter.

Fixes: 22b46c45fb9b ("iio:gyro:bmg160 Gyro Sensor driver")
Signed-off-by: Stepan Ionichev <sozdayvek@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/gyro/bmg160_core.c

index 38394b5f32755f4fe6eff68315c67e699b6ee401..58963f3ea186f00db3cc888a33cc6aef62ab4429 100644 (file)
@@ -201,6 +201,9 @@ static int bmg160_get_filter(struct bmg160_data *data, int *val)
                        break;
        }
 
+       if (i == ARRAY_SIZE(bmg160_samp_freq_table))
+               return -EINVAL;
+
        *val = bmg160_samp_freq_table[i].filter;
 
        return ret ? ret : IIO_VAL_INT;
@@ -218,6 +221,9 @@ static int bmg160_set_filter(struct bmg160_data *data, int val)
                        break;
        }
 
+       if (i == ARRAY_SIZE(bmg160_samp_freq_table))
+               return -EINVAL;
+
        ret = regmap_write(data->regmap, BMG160_REG_PMU_BW,
                           bmg160_samp_freq_table[i].bw_bits);
        if (ret < 0) {