From 97e20f3d8630510a1fbb3e066c0f9bf02d8befde Mon Sep 17 00:00:00 2001 From: Bryam Vargas Date: Mon, 22 Jun 2026 03:55:13 -0500 Subject: [PATCH] iio: imu: inv_icm45600: clamp the device-reported FIFO sample count inv_icm45600_buffer_fifo_read() uses the FIFO_COUNT the device reports, unclamped, as the length of a regmap_noinc_read() into the fixed INV_ICM45600_FIFO_SIZE_MAX (8 KiB) st->fifo.data buffer. The only bound is the caller's "max", which the interrupt path skips (it passes 0). A device, or an attacker on the bus, reporting up to 65535 makes the read as large as ~1 MiB: a heap out-of-bounds write of device-controlled data. Clamp st->fifo.count to the buffer capacity before the read, and allocate the buffer with the same INV_ICM45600_FIFO_SIZE_MAX define, so the bound and the allocation reference one constant. The clamp is a no-op for conforming hardware. Signed-off-by: Bryam Vargas Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_icm45600/inv_icm45600_buffer.c | 7 +++++-- drivers/iio/imu/inv_icm45600/inv_icm45600_core.c | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/iio/imu/inv_icm45600/inv_icm45600_buffer.c b/drivers/iio/imu/inv_icm45600/inv_icm45600_buffer.c index 2b9ea317385c..42111c543d3c 100644 --- a/drivers/iio/imu/inv_icm45600/inv_icm45600_buffer.c +++ b/drivers/iio/imu/inv_icm45600/inv_icm45600_buffer.c @@ -422,8 +422,11 @@ int inv_icm45600_buffer_fifo_read(struct inv_icm45600_state *st, if (max > 0 && fifo_nb > max) fifo_nb = max; - /* Try to read all FIFO data in internal buffer. */ - st->fifo.count = fifo_nb * packet_size; + /* + * Read all FIFO data into the internal buffer, clamping the + * device-reported count to the buffer capacity. + */ + st->fifo.count = min(fifo_nb * packet_size, INV_ICM45600_FIFO_SIZE_MAX); ret = regmap_noinc_read(st->map, INV_ICM45600_REG_FIFO_DATA, st->fifo.data, st->fifo.count); if (ret == -ENOTSUPP || ret == -EFBIG) { diff --git a/drivers/iio/imu/inv_icm45600/inv_icm45600_core.c b/drivers/iio/imu/inv_icm45600/inv_icm45600_core.c index d49053161a65..c1d7aa7e950d 100644 --- a/drivers/iio/imu/inv_icm45600/inv_icm45600_core.c +++ b/drivers/iio/imu/inv_icm45600/inv_icm45600_core.c @@ -716,7 +716,7 @@ int inv_icm45600_core_probe(struct regmap *regmap, const struct inv_icm45600_chi dev_set_drvdata(dev, st); - st->fifo.data = devm_kzalloc(dev, 8192, GFP_KERNEL); + st->fifo.data = devm_kzalloc(dev, INV_ICM45600_FIFO_SIZE_MAX, GFP_KERNEL); if (!st->fifo.data) return -ENOMEM;