From 9003bf7c2abf046bbf30b61708ec7a151331c98e Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Tue, 6 Oct 2026 17:46:47 +0200 Subject: [PATCH] audio: base_fw: bound host pipelines_count in pipeline list query basefw_pipeline_list_info_get() reads pipelines_count straight from the host mailbox (ipc4_get_pipeline_data()) and uses it as the bound of a loop that probes every pipeline instance id and emits a trace error for each miss. Nothing validates the value, so a GET_LARGE_CONFIG request for IPC4_PIPELINE_LIST_INFO_GET with e.g. pipelines_count = 0xbb0000bb spins the IPC thread for ~3 billion iterations. The signed int loop counter also overflows at INT_MAX (UBSan: base_fw.c:535 "2147483647 + 1 cannot be represented in type 'int'"). Reject pipelines_count above IPC4_MAX_PPL_COUNT, which the firmware already advertises to the host as the pipeline limit in the FW config TLV, and make the loop counter unsigned to match the field type. Signed-off-by: Tomasz Leman --- src/audio/base_fw.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/audio/base_fw.c b/src/audio/base_fw.c index 257076be35d2..fb29dabffc65 100644 --- a/src/audio/base_fw.c +++ b/src/audio/base_fw.c @@ -532,10 +532,16 @@ __cold static int basefw_pipeline_list_info_get(uint32_t *data_offset, char *dat pipeline_data = ipc4_get_pipeline_data_wrapper(); ppl_data->pipelines_count = 0; - for (int ppl = 0; ppl < pipeline_data->pipelines_count; ppl++) { + if (pipeline_data->pipelines_count > IPC4_MAX_PPL_COUNT) { + tr_err(&ipc_tr, "pipelines_count %u exceeds maximum %u", + pipeline_data->pipelines_count, IPC4_MAX_PPL_COUNT); + return IPC4_ERROR_INVALID_PARAM; + } + + for (uint32_t ppl = 0; ppl < pipeline_data->pipelines_count; ppl++) { ipc_pipe = ipc_get_pipeline_by_id(ipc, ppl); if (!ipc_pipe) - tr_err(&ipc_tr, "No pipeline with instance_id = %d", ppl); + tr_err(&ipc_tr, "No pipeline with instance_id = %u", ppl); else ppl_data->ppl_id[ppl_data->pipelines_count++] = ipc_pipe->pipeline->pipeline_id;