mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v3] iio: accel: bmc150: clamp the device-reported FIFO frame count
@ 2026-06-17  1:56 Bryam Vargas via B4 Relay
  2026-06-17  9:31 ` Andy Shevchenko
  2026-06-21 17:55 ` Jonathan Cameron
  0 siblings, 2 replies; 3+ messages in thread
From: Bryam Vargas via B4 Relay @ 2026-06-17  1:56 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Nuno Sá, David Lechner, Andy Shevchenko, linux-kernel, linux-iio

From: Bryam Vargas <hexlabsecurity@proton.me>

__bmc150_accel_fifo_flush() transfers the frame count the device reports
in FIFO_STATUS into an on-stack buffer sized for BMC150_ACCEL_FIFO_LENGTH
(32) samples, but the count is masked to 7 bits (0..127) and the optional
caller budget does not bound the flush-all path. A device, or an attacker
on the I2C/SPI bus, reporting up to 127 frames overflows the buffer by up
to 570 bytes: a stack out-of-bounds write.

Clamp the count to BMC150_ACCEL_FIFO_LENGTH before the transfer, mirroring
the clamp already applied in bmc150_accel_set_watermark(). Conforming
hardware reports at most that many frames and is unaffected.

Fixes: 3bbec9773389 ("iio: bmc150_accel: add support for hardware fifo")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
---
v3 (Andy [2], [3]): shrink the commit message and move the register/byte
detail below the cut; fold the caller budget and the clamp into min3()/min()
per Andy [3] (no functional change; make W=1 clean).
v2 (Jonathan [1]): clamp with min() instead of min_t(u8, ...).

[1] https://lore.kernel.org/all/20260614141146.697dde04@jic23-huawei/
[2] https://lore.kernel.org/all/ajEMUChqvxGzSLl_@ashevche-desk.local/
[3] https://lore.kernel.org/all/ajELw0x5DiyMuFYZ@ashevche-desk.local/
v1: https://lore.kernel.org/all/20260613-b4-disp-24d6b15f-v1-1-f5c3fe7294fc@proton.me/
v2: https://lore.kernel.org/all/20260615-b4-disp-ef4f7a59-v2-1-af5e980bcdd7@proton.me/

count = val & 0x7F is 0..127; the only other limit is the optional caller
budget, which does not constrain the flush-all path (samples == 0).
bmc150_accel_fifo_transfer() reads count * 6 bytes, so a count of up to 127
writes up to 762 bytes into the 192-byte buffer (up to 570 past its end),
clobbering the stack canary, saved registers and the return address.

Reachable on every FIFO flush (watermark IRQ or the sysfs buffer-disable
path). Verified with an in-kernel KASAN litmus (CONFIG_KASAN_STACK=y) and a
userspace ASan model on x86_64 and i386: without the clamp a device
reporting 127 frames drives the transfer past the 192-byte buffer (stack
out-of-bounds write, both ABIs); with the clamp it is bounded to 32.
Reproducer and full logs available on request.
---
 drivers/iio/accel/bmc150-accel-core.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c
index 2398eb7e12cd..ecaa4782d847 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -988,8 +988,10 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
 	do_div(sample_period, count);
 	tstamp = data->timestamp - (count - 1) * sample_period;
 
-	if (samples && count > samples)
-		count = samples;
+	if (samples)
+		count = min3(count, samples, BMC150_ACCEL_FIFO_LENGTH);
+	else
+		count = min(count, BMC150_ACCEL_FIFO_LENGTH);
 
 	ret = bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);
 	if (ret)

---
base-commit: 8e65320d91cdc3b241d4b94855c88459b91abf66
change-id: 20260616-b4-disp-9546bfb4-a26c55f33efc

Best regards,
-- 
Bryam Vargas <hexlabsecurity@proton.me>



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-06-21 17:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-17  1:56 [PATCH v3] iio: accel: bmc150: clamp the device-reported FIFO frame count Bryam Vargas via B4 Relay
2026-06-17  9:31 ` Andy Shevchenko
2026-06-21 17:55 ` Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®