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 dc6877059f57..f5ead3a93368 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; } @@ -68,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); @@ -107,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; @@ -118,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) @@ -137,8 +157,6 @@ int mux_params(struct processing_module *mod) if (ret < 0) return ret; - set_mux_params(mod, cfg); - - return ret; + return set_mux_params(mod, cfg); } #endif /* CONFIG_COMP_MUX */