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
15 changes: 15 additions & 0 deletions src/ipc/ipc4/handler-user.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,21 @@ static int ipc4_set_pipeline_state(struct ipc4_message_request *ipc4)

if (state.extension.r.multi_ppl) {
ppl_count = ppl_data->pipelines_count;
/*
* pipelines_count is read straight from the host-provided
* mailbox payload, so cap it at what the mailbox can
* physically hold. Anything larger means the host promised
* more ppl_id[] entries than fit in MAILBOX_HOSTBOX, and
* dereferencing the flex array would read out of bounds.
*/
if (ppl_count > (MAILBOX_HOSTBOX_SIZE -
sizeof(struct ipc4_pipeline_set_state_data)) /
sizeof(uint32_t)) {
ipc_cmd_err(&ipc_tr,
"ipc: pipelines_count %u exceeds mailbox bound",
ppl_count);
return IPC4_ERROR_INVALID_PARAM;
}
ppl_id = ppl_data->ppl_id;
dcache_invalidate_region((__sparse_force void __sparse_cache *)ppl_id,
sizeof(int) * ppl_count);
Expand Down
1 change: 1 addition & 0 deletions src/ipc/ipc4/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ __cold static int ipc4_create_pipeline_payload_decode(char *data,
if (size > MAILBOX_HOSTBOX_SIZE) {
tr_err(&ipc_tr, "Payload size too large: %u : %#x", hdr->payload_words,
*((uint32_t *)hdr));
return -EINVAL;
}
tr_info(&ipc_tr, "payload size %u array %u: %#x", hdr->payload_words, hdr->data_obj_array,
*((uint32_t *)hdr));
Expand Down
4 changes: 2 additions & 2 deletions src/platform/posix/fuzz.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t sz)
}

/* Provide the fuzz data to the embedded OS as an interrupt, with
* "DMA-like" data placed into native_fuzz_buf/sz
* "DMA-like" data placed into posix_fuzz_buf/sz.
*/
posix_fuzz_buf = (void *)data;
posix_fuzz_buf = data;
posix_fuzz_sz = sz;
hw_irq_ctrl_set_irq(CONFIG_ZEPHYR_POSIX_FUZZ_IRQ);

Expand Down
23 changes: 18 additions & 5 deletions src/platform/posix/include/platform/lib/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,38 @@
#define PLATFORM_HOST_PLATFORM_MEMORY_H

#include <stdint.h>
#include <ipc/header.h>

#define PLATFORM_DCACHE_ALIGN 64
#define uncache_to_cache(addr) (addr)
#define cache_to_uncache(addr) (addr)

/*
* Mailbox base macros must yield byte-pointer arithmetic so that the
* generic mailbox API in `sof/src/include/sof/lib/mailbox.h`
* (`MAILBOX_HOSTBOX_BASE + offset`, etc., where `offset` is a byte
* offset) addresses the intended byte. The backing storage is
* declared as `uint32_t[]` only for natural-alignment; addressing is
* done through a `uint8_t *` cast so byte offsets do not get scaled
* by `sizeof(uint32_t)`. Every other SOF platform defines these
* bases as plain byte addresses (integer literals or
* `SRAM_INBOX_BASE`), so the cast keeps POSIX consistent with that
* ABI.
*/
extern uint32_t posix_hostbox[];
#define MAILBOX_HOSTBOX_SIZE 1024
#define MAILBOX_HOSTBOX_BASE (&posix_hostbox[0])
#define MAILBOX_HOSTBOX_SIZE SOF_IPC_MSG_MAX_SIZE
#define MAILBOX_HOSTBOX_BASE ((uint8_t *)&posix_hostbox[0])

extern uint32_t posix_dspbox[];
#define MAILBOX_DSPBOX_SIZE 4096
#define MAILBOX_DSPBOX_BASE (&posix_dspbox[0])
#define MAILBOX_DSPBOX_BASE ((uint8_t *)&posix_dspbox[0])

extern uint32_t posix_stream[];
#define MAILBOX_STREAM_SIZE 4096
#define MAILBOX_STREAM_BASE (&posix_stream[0])
#define MAILBOX_STREAM_BASE ((uint8_t *)&posix_stream[0])

extern uint32_t posix_trace[];
#define MAILBOX_TRACE_BASE (&posix_trace[0])
#define MAILBOX_TRACE_BASE ((uint8_t *)&posix_trace[0])
#define MAILBOX_TRACE_SIZE 4096

#define PLATFORM_HEAP_SYSTEM 1
Expand Down
32 changes: 30 additions & 2 deletions src/platform/posix/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ static void posix_ipc_isr(void *arg)
ipc_schedule_process(global_ipc);
}

// External symbols set up by the fuzzing layer
extern uint8_t *posix_fuzz_buf, posix_fuzz_sz;
// External symbols set up by the fuzzing layer in fuzz.c.
extern const uint8_t *posix_fuzz_buf;
extern size_t posix_fuzz_sz;

// Lots of space. Should really synchronize with the -max_len
// parameter to libFuzzer (defaults to 4096), but that requires
Expand Down Expand Up @@ -145,11 +146,38 @@ static void fuzz_isr(const void *arg)
// ipc_platform_compact_read_msg(), writing 8 bytes unconditionally on
// the header object it receives, which is then returned here, and
// then passed to ipc_cmd().
//
// The harness also mirrors the framed message into MAILBOX_HOSTBOX so
// that handlers reading payload directly from the hostbox region
// (large_config_set/get, set_dx, set_pipeline_state, vendor_config and
// friends in ipc4/handler-user.c and ipc4/handler-kernel.c) observe
// the fuzz bytes rather than stale or zero-filled memory.
//
// The two IPC majors split header and payload differently:
//
// * IPC3 carries the header in-band at the start of the message, and
// mailbox_validate() walks the full message starting from offset 0
// of the hostbox. The full message is mirrored as-is.
//
// * IPC4 splits the 8-byte compact header (consumed via
// ipc_compact_read_msg()) from the payload, which on real hardware
// lives in HOSTBOX. The harness therefore mirrors only the
// post-header bytes, so the first dword of MAILBOX_HOSTBOX matches
// the first dword of the IPC4 payload (e.g. pipelines_count for
// SET_PIPELINE_STATE) instead of header bits.
//
// posix_hostbox is sized to SOF_IPC_MSG_MAX_SIZE (see
// platform/lib/memory.h), so the copy is always in bounds for both
// IPC3 and IPC4 message envelopes.
enum task_state ipc_platform_do_cmd(struct ipc *ipc)
{
struct ipc_cmd_hdr *hdr;

#ifdef CONFIG_IPC_MAJOR_4
memset(posix_hostbox, 0, SOF_IPC_MSG_MAX_SIZE);
memcpy(posix_hostbox,
(const uint8_t *)global_ipc->comp_data + sizeof(struct ipc_cmd_hdr),
SOF_IPC_MSG_MAX_SIZE - sizeof(struct ipc_cmd_hdr));
hdr = ipc_compact_read_msg();
#else
Comment thread
tmleman marked this conversation as resolved.
memcpy(posix_hostbox, global_ipc->comp_data, SOF_IPC_MSG_MAX_SIZE);
Expand Down
Loading