From c2ea983775e7cb8e3fb2977e779a309351ef7447 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 29 May 2026 23:38:27 +0200 Subject: [PATCH] ipc4: handler: reject get_large_config vendor payload larger than hostbox ipc4_get_large_config_module_instance() reads config.extension.r.data_off_size straight from the host message and, for the VENDOR_CONFIG_PARAM case, uses it without an upper bound: * dcache_invalidate_region() is asked to invalidate that many bytes starting at MAILBOX_HOSTBOX_BASE, and * ipc4_get_vendor_config_module_instance() computes tl_count = data_off_size / sizeof(struct sof_tl) and walks that many TL records straight out of the hostbox. data_off_size is a 20-bit field, so it can claim up to ~1 MB while the hostbox is only MAILBOX_HOSTBOX_SIZE (SOF_IPC_MSG_MAX_SIZE) bytes. The symmetric set path already rejects this in ipc4_set_vendor_config_module_instance() ("data_off_size ... > MAILBOX_HOSTBOX_SIZE"), the get path was missing the same guard, leaving a cache-maintenance over-range on real hardware and an out-of-bounds hostbox read for any vendor param that returns success with a zero-length value (which keeps produced_data from advancing the DSPBOX cap that otherwise terminates the loop early). Found by audit while reviewing the IPC4 hostbox readers surfaced by the fuzz harness, not by a live crash: on native_sim CONFIG_CACHE is unset so the invalidate is a no-op, and the common TL walk is bounded in practice by the DSPBOX size check. Convert the missing bound into a hard rejection before the region is touched, mirroring the set path. Signed-off-by: Tomasz Leman --- src/ipc/ipc4/handler-user.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ipc/ipc4/handler-user.c b/src/ipc/ipc4/handler-user.c index df243fa6ff58..5a5f3d6d6f32 100644 --- a/src/ipc/ipc4/handler-user.c +++ b/src/ipc/ipc4/handler-user.c @@ -1040,6 +1040,14 @@ __cold static int ipc4_get_large_config_module_instance(struct ipc4_message_requ /* check for vendor param first */ if (config.extension.r.large_param_id == VENDOR_CONFIG_PARAM) { + /* data_off_size is a 20-bit host-controlled field, so it can + * claim far more than the hostbox can physically hold. + */ + if (data_offset > MAILBOX_HOSTBOX_SIZE) { + ipc_cmd_err(&ipc_tr, "data_off_size %u exceeds mailbox bound", + data_offset); + return IPC4_INVALID_CONFIG_DATA_STRUCT; + } /* For now only vendor_config case uses payload from hostbox */ dcache_invalidate_region((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, config.extension.r.data_off_size);