Skip to content

Commit 607e39d

Browse files
committed
ipc3: bound host page count before page table DMA and parsing
The host-supplied ring->pages drives both the page table DMA transfer length (20 bits per page) and the DSP-side descriptor allocations, but only ring->size was sanity checked. A large page count could overflow the fixed-size page table buffer and wrap the page-count multiplication. Reject a zero or too-large page count at the single entry point before any use. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
1 parent 3f7738d commit 607e39d

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

src/ipc/ipc3/host-page-table.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,25 @@
1616

1717
LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL);
1818

19+
/*
20+
* Size in bytes of the DSP-side buffer that receives the compressed host page
21+
* table. DSP targets define PLATFORM_PAGE_TABLE_SIZE; the host/library builds
22+
* (e.g. testbench, fuzzer) allocate it as HOST_PAGE_SIZE in drivers/host/ipc.c
23+
* and do not define PLATFORM_PAGE_TABLE_SIZE, so fall back to that.
24+
*/
25+
#ifndef PLATFORM_PAGE_TABLE_SIZE
26+
#define PLATFORM_PAGE_TABLE_SIZE HOST_PAGE_SIZE
27+
#endif
28+
29+
/*
30+
* The compressed page table stores one 20-bit entry per host page, so the
31+
* number of pages whose entries fit in the page table buffer is
32+
* (buffer bytes * 8 bits/byte) / 20 bits/page.
33+
*/
34+
#define HOST_PAGE_TABLE_BITS_PER_PAGE 20
35+
#define HOST_PAGE_TABLE_MAX_PAGES \
36+
(PLATFORM_PAGE_TABLE_SIZE * 8 / HOST_PAGE_TABLE_BITS_PER_PAGE)
37+
1938
/*
2039
* Parse the host page tables and create the audio DMA SG configuration
2140
* for host audio DMA buffer. This involves creating a dma_sg_elem for each
@@ -216,6 +235,19 @@ int ipc_process_host_buffer(struct ipc *ipc,
216235
struct ipc_data_host_buffer *data_host_buffer;
217236
int err;
218237

238+
/*
239+
* The host-supplied page count is used both to size DSP-side
240+
* allocations and to compute the DMA transfer length for the
241+
* compressed page table. Reject a count that would not fit in the
242+
* page table buffer before doing any arithmetic that could overflow
243+
* (ring->pages * 20). pages == 0 is also invalid and would underflow
244+
* the ring->size sanity check in ipc_parse_page_descriptors().
245+
*/
246+
if (ring->pages == 0 || ring->pages > HOST_PAGE_TABLE_MAX_PAGES) {
247+
tr_err(&ipc_tr, "ipc: invalid page count %u", ring->pages);
248+
return -EINVAL;
249+
}
250+
219251
data_host_buffer = ipc_platform_get_host_buffer(ipc);
220252
dma_sg_init(elem_array);
221253

0 commit comments

Comments
 (0)