From ddc9b53abe2014f3bc5aa7f96d2aee0f27386f5a Mon Sep 17 00:00:00 2001 From: Adrian Bonislawski Date: Thu, 11 Jun 2026 16:59:35 +0200 Subject: [PATCH 1/3] mux: ipc4: validate channels_count before building mask build_config() looped over host-supplied channels_count writing streams[].mask[] (size PLATFORM_MAX_CHANNELS), overflowing it. Reject counts above the max. Signed-off-by: Adrian Bonislawski --- src/audio/mux/mux_ipc4.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/audio/mux/mux_ipc4.c b/src/audio/mux/mux_ipc4.c index dc6877059f57..ed7195fc0e6b 100644 --- a/src/audio/mux/mux_ipc4.c +++ b/src/audio/mux/mux_ipc4.c @@ -36,9 +36,21 @@ static int build_config(struct processing_module *mod, struct mux_data *cfg) { struct comp_dev *dev = mod->dev; struct comp_data *cd = module_get_private_data(mod); + uint32_t base_ch = cfg->base_cfg.audio_fmt.channels_count; + uint32_t ref_ch = cfg->reference_format.channels_count; + uint32_t out_ch = cfg->output_format.channels_count; int mask = 1; int i; + /* base+reference map 1:1 to contiguous output channels: sink width + * must equal their sum and fit the 8-bit output mask + */ + if (base_ch + ref_ch > PLATFORM_MAX_CHANNELS || out_ch != base_ch + ref_ch) { + comp_err(dev, "invalid channel count: base %u + reference %u -> output %u (max %d)", + base_ch, ref_ch, out_ch, PLATFORM_MAX_CHANNELS); + return -EINVAL; + } + cd->config.num_streams = MUX_MAX_STREAMS; /* clear masks */ @@ -46,12 +58,12 @@ static int build_config(struct processing_module *mod, struct mux_data *cfg) memset(cd->config.streams[i].mask, 0, sizeof(cd->config.streams[i].mask)); /* Setting masks for streams */ - for (i = 0; i < cfg->base_cfg.audio_fmt.channels_count; i++) { + for (i = 0; i < base_ch; i++) { cd->config.streams[0].mask[i] = mask; mask <<= 1; } - for (i = 0; i < cfg->reference_format.channels_count; i++) { + for (i = 0; i < ref_ch; i++) { cd->config.streams[1].mask[i] = mask; mask <<= 1; } From 75c0ff7e049ad68623688e0bd836642cab8f1e3e Mon Sep 17 00:00:00 2001 From: Adrian Bonislawski Date: Thu, 11 Jun 2026 17:00:01 +0200 Subject: [PATCH 2/3] mux: ipc4: reject out-of-range source queue ID set_mux_params() indexed streams[] with the host-supplied bind queue ID without bounds, allowing an OOB write. Validate against MUX_MAX_STREAMS and propagate the error. Signed-off-by: Adrian Bonislawski --- src/audio/mux/mux_ipc4.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/audio/mux/mux_ipc4.c b/src/audio/mux/mux_ipc4.c index ed7195fc0e6b..5d81e72e92a2 100644 --- a/src/audio/mux/mux_ipc4.c +++ b/src/audio/mux/mux_ipc4.c @@ -80,7 +80,7 @@ static int build_config(struct processing_module *mod, struct mux_data *cfg) * set up param then verify param. BTW for IPC3 path, the param is sent by * host driver. */ -static void set_mux_params(struct processing_module *mod, struct mux_data *cfg) +static int set_mux_params(struct processing_module *mod, struct mux_data *cfg) { struct sof_ipc_stream_params *params = mod->stream_params; struct comp_data *cd = module_get_private_data(mod); @@ -119,6 +119,12 @@ static void set_mux_params(struct processing_module *mod, struct mux_data *cfg) comp_dev_for_each_producer(dev, source) { j = IPC4_SINK_QUEUE_ID(buf_get_id(source)); + /* host-supplied queue ID indexes streams[] */ + if (j >= MUX_MAX_STREAMS) { + comp_err(dev, "invalid source queue ID %d (valid range 0..%d)", + j, MUX_MAX_STREAMS - 1); + return -EINVAL; + } cd->config.streams[j].pipeline_id = buffer_pipeline_id(source); if (j == BASE_CFG_QUEUED_ID) audio_fmt = &cfg->base_cfg.audio_fmt; @@ -130,6 +136,8 @@ static void set_mux_params(struct processing_module *mod, struct mux_data *cfg) } mux_prepare_look_up_table(mod); + + return 0; } int mux_params(struct processing_module *mod) @@ -149,7 +157,7 @@ int mux_params(struct processing_module *mod) if (ret < 0) return ret; - set_mux_params(mod, cfg); + ret = set_mux_params(mod, cfg); return ret; } From 0c6ba922faa2a30f3d2b3ca2252112a64540ec0c Mon Sep 17 00:00:00 2001 From: Adrian Bonislawski Date: Thu, 11 Jun 2026 17:00:18 +0200 Subject: [PATCH 3/3] mux: ipc3: enforce mux_mix_check result mux_set_values() logged a mux_mix_check() failure but still returned success, applying an invalid routing matrix. Return -EINVAL, matching the IPC4 path. Signed-off-by: Adrian Bonislawski --- src/audio/mux/mux_ipc3.c | 4 +++- src/audio/mux/mux_ipc4.c | 4 +--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/audio/mux/mux_ipc3.c b/src/audio/mux/mux_ipc3.c index fb00030b5814..b8454043e0fd 100644 --- a/src/audio/mux/mux_ipc3.c +++ b/src/audio/mux/mux_ipc3.c @@ -70,8 +70,10 @@ static int mux_set_values(struct processing_module *mod) } if (cd->comp_type == SOF_COMP_MUX) { - if (mux_mix_check(cfg)) + if (mux_mix_check(cfg)) { comp_err(dev, "mux component is not able to mix channels"); + return -EINVAL; + } } for (i = 0; i < cfg->num_streams; i++) { diff --git a/src/audio/mux/mux_ipc4.c b/src/audio/mux/mux_ipc4.c index 5d81e72e92a2..f5ead3a93368 100644 --- a/src/audio/mux/mux_ipc4.c +++ b/src/audio/mux/mux_ipc4.c @@ -157,8 +157,6 @@ int mux_params(struct processing_module *mod) if (ret < 0) return ret; - ret = set_mux_params(mod, cfg); - - return ret; + return set_mux_params(mod, cfg); } #endif /* CONFIG_COMP_MUX */