Re: [PATCH v5 2/3] rust: spi: add SPI driver abstractions
From: Karl Mehltretter
Date: Mon Oct 26 2026 - 23:36:58 EST
> + pub fn write_then_read(&self, write_buf: &[u8], read_buf: &mut [u8]) -> Result {
> + let n_tx = u32::try_from(write_buf.len())?;
> + let n_rx = u32::try_from(read_buf.len())?;
Could we check n_tx.checked_add(n_rx) here? spi_write_then_read() adds
these as unsigned int when sizing its bounce buffer. The individual
conversions don't prevent the sum from wrapping.
On a 64-bit kernel, VVec can provide two disjoint 2 GiB slices. It uses
vmalloc, so the kmalloc limit doesn't bound the inputs. With a bound
device and a successful 4 GiB allocation:
use kernel::alloc::{flags::GFP_KERNEL, VVec};
let mut storage = VVec::<u8>::zeroed(1usize << 32, GFP_KERNEL)?;
let (tx, rx) = storage.split_at_mut(1usize << 31);
dev.write_then_read(tx, rx)?;
Both lengths fit in u32, but their sum wraps to zero. C then selects
or allocates only SPI_BUFSIZ bytes and attempts to copy 2 GiB into it.
The allocation size has already wrapped before kmalloc sees it.
The C helper is intended for small transfers, but this safe wrapper
accepts arbitrary slices. Bound doesn't constrain their lengths.
Found during source review with AI assistance. I haven't compiled or
run this example, and I don't know of an in-tree caller passing such
large buffers.
Thanks,
Karl