Skip to content

Commit b20c57b

Browse files
committed
ipc4: helper: reject pipeline ext payload larger than hostbox
ipc4_create_pipeline_payload_decode() reads pipeline extension objects out of the hostbox region. The function already validates that `size = hdr->payload_words * 4` is at least `sizeof(*hdr)`, but the symmetric upper bound check against MAILBOX_HOSTBOX_SIZE was emitting tr_err() and continuing. Once the loop is entered, every per-object bounds check at lines 290 and 299 is expressed relative to the attacker-controlled `size`, so a payload header that claims `payload_words` significantly larger than the mailbox lets the decoder walk `obj` arbitrarily far past the end of MAILBOX_HOSTBOX_BASE while dereferencing `obj->object_words` and `obj->object_id`. This was unreachable on real hardware because the host kernel is trusted to bound the payload, and unreachable in the SOF fuzz harness until commit "fuzz: posix: mirror IPC4 payload into MAILBOX_HOSTBOX" wired the fuzz-controlled bytes into the hostbox. A 60 s libFuzzer/ASan campaign with the IPC4 dictionary then surfaced a reproducible global-buffer-overflow at helper.c:298 (READ of size 4 at `posix_hostbox + 4096`). Convert the existing warning into a hard rejection so the decoder returns -EINVAL before entering the object-walk loop. Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
1 parent 6386ffa commit b20c57b

1 file changed

Lines changed: 1 addition & 0 deletions

File tree

src/ipc/ipc4/helper.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ __cold static int ipc4_create_pipeline_payload_decode(char *data,
271271
if (size > MAILBOX_HOSTBOX_SIZE) {
272272
tr_err(&ipc_tr, "Payload size too large: %u : %#x", hdr->payload_words,
273273
*((uint32_t *)hdr));
274+
return -EINVAL;
274275
}
275276
tr_info(&ipc_tr, "payload size %u array %u: %#x", hdr->payload_words, hdr->data_obj_array,
276277
*((uint32_t *)hdr));

0 commit comments

Comments
 (0)