Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/ipc/ipc3/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,11 @@ static int comp_specific_builder(struct sof_ipc_comp *comp,
if (IPC_TAIL_IS_SIZE_INVALID(*proc))
return -EBADMSG;

if (proc->comp.hdr.size + proc->size > SOF_IPC_MSG_MAX_SIZE)
/* compare without adding the two host-supplied uint32_t values,
* which could wrap and let an oversized proc->size pass
*/
if (proc->comp.hdr.size > SOF_IPC_MSG_MAX_SIZE ||
proc->size > SOF_IPC_MSG_MAX_SIZE - proc->comp.hdr.size)
return -EBADMSG;

config->process.type = proc->type;
Expand Down
32 changes: 32 additions & 0 deletions src/ipc/ipc3/host-page-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,25 @@

LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL);

/*
* Size in bytes of the DSP-side buffer that receives the compressed host page
* table. DSP targets define PLATFORM_PAGE_TABLE_SIZE; the host/library builds
* (e.g. testbench, fuzzer) allocate it as HOST_PAGE_SIZE in drivers/host/ipc.c
* and do not define PLATFORM_PAGE_TABLE_SIZE, so fall back to that.
*/
#ifndef PLATFORM_PAGE_TABLE_SIZE
#define PLATFORM_PAGE_TABLE_SIZE HOST_PAGE_SIZE
#endif

/*
* The compressed page table stores one 20-bit entry per host page, so the
* number of pages whose entries fit in the page table buffer is
* (buffer bytes * 8 bits/byte) / 20 bits/page.
*/
#define HOST_PAGE_TABLE_BITS_PER_PAGE 20
#define HOST_PAGE_TABLE_MAX_PAGES \
(PLATFORM_PAGE_TABLE_SIZE * 8 / HOST_PAGE_TABLE_BITS_PER_PAGE)

/*
* Parse the host page tables and create the audio DMA SG configuration
* for host audio DMA buffer. This involves creating a dma_sg_elem for each
Expand Down Expand Up @@ -216,6 +235,19 @@ int ipc_process_host_buffer(struct ipc *ipc,
struct ipc_data_host_buffer *data_host_buffer;
int err;

/*
* The host-supplied page count is used both to size DSP-side
* allocations and to compute the DMA transfer length for the
* compressed page table. Reject a count that would not fit in the
* page table buffer before doing any arithmetic that could overflow
* (ring->pages * 20). pages == 0 is also invalid and would underflow
* the ring->size sanity check in ipc_parse_page_descriptors().
*/
if (ring->pages == 0 || ring->pages > HOST_PAGE_TABLE_MAX_PAGES) {
tr_err(&ipc_tr, "ipc: invalid page count %u", ring->pages);
return -EINVAL;
}

data_host_buffer = ipc_platform_get_host_buffer(ipc);
dma_sg_init(elem_array);

Expand Down
Loading