[PATCH] iio: pressure: bmp280: fix out-of-bounds access in sampling frequency lookup

Hui Su posted 1 patch 1 month, 3 weeks ago
There is a newer version of this series
drivers/iio/pressure/bmp280-core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
[PATCH] iio: pressure: bmp280: fix out-of-bounds access in sampling frequency lookup
Posted by Hui Su 1 month, 3 weeks ago
The sampling frequency tables store each frequency as an integer part
and a fractional part in micro units. num_sampling_freq_avail is
initialized to the number of flattened integer elements because
read_avail() returns the table as a flat array.

bmp280_write_sampling_frequency(), however, indexes the same table as a
two-dimensional array and uses num_sampling_freq_avail as the number of
rows. This makes the lookup walk past the end of the table when an
unsupported sampling frequency is written.

Convert the flattened element count back to the number of rows before
iterating over the table.

Fixes: 10b40ffba2f9 ("iio: pressure: bmp280: Add more tunable config parameters for BMP380")
Cc: stable@vger.kernel.org
Signed-off-by: Hui Su <sh_def@163.com>
---
 drivers/iio/pressure/bmp280-core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index 990340a9b10c..ddd2de3c35ba 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -836,7 +836,8 @@ static int bmp280_write_sampling_frequency(struct bmp280_data *data,
 					   int val, int val2)
 {
 	const int (*avail)[2] = data->chip_info->sampling_freq_avail;
-	const int n = data->chip_info->num_sampling_freq_avail;
+	const int n = data->chip_info->num_sampling_freq_avail /
+		      ARRAY_SIZE(*avail);
 	int ret, prev;
 	int i;
 
-- 
2.43.0
Re: [PATCH] iio: pressure: bmp280: fix out-of-bounds access in sampling frequency lookup
Posted by Andy Shevchenko 1 month, 3 weeks ago
On Wed, Aug 05, 2026 at 03:41:27PM +0800, Hui Su wrote:
> The sampling frequency tables store each frequency as an integer part
> and a fractional part in micro units. num_sampling_freq_avail is
> initialized to the number of flattened integer elements because
> read_avail() returns the table as a flat array.
> 
> bmp280_write_sampling_frequency(), however, indexes the same table as a
> two-dimensional array and uses num_sampling_freq_avail as the number of
> rows. This makes the lookup walk past the end of the table when an
> unsupported sampling frequency is written.
> 
> Convert the flattened element count back to the number of rows before
> iterating over the table.

...

> static int bmp280_write_sampling_frequency(struct bmp280_data *data,
>  					   int val, int val2)
>  {
>  	const int (*avail)[2] = data->chip_info->sampling_freq_avail;
> -	const int n = data->chip_info->num_sampling_freq_avail;
> +	const int n = data->chip_info->num_sampling_freq_avail /
> +		      ARRAY_SIZE(*avail);

For the consistency's sake use just plain 2 as initialisators do.

...

Nice catch! This seems to work because the page is present, but after this
array it contains some garbage that doesn't induce page fault, otherwise this
must have led to oops very easily (and no one reported it before).

-- 
With Best Regards,
Andy Shevchenko
Re: [PATCH] iio: pressure: bmp280: fix out-of-bounds access in sampling frequency lookup
Posted by Joshua Crofts 1 month, 3 weeks ago
On Wed,  5 Aug 2026 15:41:27 +0800
Hui Su <sh_def@163.com> wrote:

> The sampling frequency tables store each frequency as an integer part
> and a fractional part in micro units. num_sampling_freq_avail is
> initialized to the number of flattened integer elements because
> read_avail() returns the table as a flat array.
> 
> bmp280_write_sampling_frequency(), however, indexes the same table as a
> two-dimensional array and uses num_sampling_freq_avail as the number of
> rows. This makes the lookup walk past the end of the table when an
> unsupported sampling frequency is written.
> 
> Convert the flattened element count back to the number of rows before
> iterating over the table.
> 
> Fixes: 10b40ffba2f9 ("iio: pressure: bmp280: Add more tunable config parameters for BMP380")
> Cc: stable@vger.kernel.org
> Signed-off-by: Hui Su <sh_def@163.com>
> ---

LGTM

Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>

-- 
Kind regards,
Joshua Crofts
[PATCH v2] iio: pressure: bmp280: fix out-of-bounds access in sampling frequency lookup
Posted by Hui Su 1 month, 3 weeks ago
The sampling frequency tables store each frequency as an integer part and
a fractional part in micro units. num_sampling_freq_avail is initialized
to the number of flattened integer elements because read_avail() returns
the table as a flat array.

bmp280_write_sampling_frequency(), however, indexes the same table as a
two-dimensional array and uses num_sampling_freq_avail as the number of
rows. Convert the flattened element count back to the number of rows
before iterating over the table.

Fixes: 10b40ffba2f9 ("iio: pressure: bmp280: Add more tunable config parameters for BMP380")
Cc: stable@vger.kernel.org
Signed-off-by: Hui Su <sh_def@163.com>
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
---
Changes in v2:
- Use plain 2 as the divisor, as suggested by Andy Shevchenko.
- Add Joshua Crofts' Reviewed-by tag.
Link: https://lore.kernel.org/lkml/20260805074127.473731-1-sh_def@163.com/

 drivers/iio/pressure/bmp280-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index 990340a9b10c..dbe42233c81d 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -836,7 +836,7 @@ static int bmp280_write_sampling_frequency(struct bmp280_data *data,
 					   int val, int val2)
 {
 	const int (*avail)[2] = data->chip_info->sampling_freq_avail;
-	const int n = data->chip_info->num_sampling_freq_avail;
+	const int n = data->chip_info->num_sampling_freq_avail / 2;
 	int ret, prev;
 	int i;
 
-- 
2.43.0
Re: [PATCH v2] iio: pressure: bmp280: fix out-of-bounds access in sampling frequency lookup
Posted by Jonathan Cameron 1 month, 2 weeks ago
On Tue, 11 Aug 2026 10:52:53 +0800
Hui Su <sh_def@163.com> wrote:

> The sampling frequency tables store each frequency as an integer part and
> a fractional part in micro units. num_sampling_freq_avail is initialized
> to the number of flattened integer elements because read_avail() returns
> the table as a flat array.
> 
> bmp280_write_sampling_frequency(), however, indexes the same table as a
> two-dimensional array and uses num_sampling_freq_avail as the number of
> rows. Convert the flattened element count back to the number of rows
> before iterating over the table.
> 
> Fixes: 10b40ffba2f9 ("iio: pressure: bmp280: Add more tunable config parameters for BMP380")
> Cc: stable@vger.kernel.org
> Signed-off-by: Hui Su <sh_def@163.com>
> Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>

Hi Hui Su

For future reference don't send a new version in reply to an older one. It rapidly looses
all usefulness as the email threads get deeper and more complex.

LGTM Applied to the fixes-togreg branch of iio.git

Note I plan to rebase that once rc1 is out and a pull request will go upstream
sometime after that.

Thanks,

Jonathan

> ---
> Changes in v2:
> - Use plain 2 as the divisor, as suggested by Andy Shevchenko.
> - Add Joshua Crofts' Reviewed-by tag.
> Link: https://lore.kernel.org/lkml/20260805074127.473731-1-sh_def@163.com/
> 
>  drivers/iio/pressure/bmp280-core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
> index 990340a9b10c..dbe42233c81d 100644
> --- a/drivers/iio/pressure/bmp280-core.c
> +++ b/drivers/iio/pressure/bmp280-core.c
> @@ -836,7 +836,7 @@ static int bmp280_write_sampling_frequency(struct bmp280_data *data,
>  					   int val, int val2)
>  {
>  	const int (*avail)[2] = data->chip_info->sampling_freq_avail;
> -	const int n = data->chip_info->num_sampling_freq_avail;
> +	const int n = data->chip_info->num_sampling_freq_avail / 2;
>  	int ret, prev;
>  	int i;
>