i3c: master: Fix out-of-bounds read in DMA bounce buffer setup

When a bounce buffer is required for DMA_TO_DEVICE transfers,
i3c_master_dma_map_single() rounds the DMA mapping length up to a
cache-line boundary:

	map_len = ALIGN(len, cache_line_size());

It then allocates the bounce buffer with:

	kmemdup(buf, map_len, GFP_KERNEL);

kmemdup() copies the full allocation size, causing it to read map_len
bytes from buf even though only len bytes are valid.  This results in an
out-of-bounds read of up to cache_line_size() - 1 bytes past the end of
the caller's buffer.

Fix the issue by allocating the bounce buffer with kzalloc() and copying
only len bytes from the original buffer.  The remaining bytes up to
map_len stay zero-filled, avoiding both the out-of-bounds read and
exposure of unrelated memory contents to the DMA engine.

Fixes: f8d9e56aeb ("i3c: master: Add helpers for DMA mapping and bounce buffer handling")
Cc: stable@vger.kernel.org
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260920151248.46936-2-adrian.hunter@intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
This commit is contained in:
Adrian Hunter 2026-09-20 18:12:31 +03:00 committed by Alexandre Belloni
parent 591980aaaa
commit 35b028b254

View File

@ -2216,12 +2216,11 @@ struct i3c_dma *i3c_master_dma_map_single(struct device *dev, void *buf,
if (force_bounce) {
dma_xfer->map_len = ALIGN(len, cache_line_size());
if (dir == DMA_FROM_DEVICE)
bounce = kzalloc(dma_xfer->map_len, GFP_KERNEL);
else
bounce = kmemdup(buf, dma_xfer->map_len, GFP_KERNEL);
bounce = kzalloc(dma_xfer->map_len, GFP_KERNEL);
if (!bounce)
return NULL;
if (dir != DMA_FROM_DEVICE)
memcpy(bounce, buf, len);
dma_buf = bounce;
}