diff --git a/src/audio/module_adapter/module/cadence_ipc4.c b/src/audio/module_adapter/module/cadence_ipc4.c index 17069b97113a..1d409e4b5a31 100644 --- a/src/audio/module_adapter/module/cadence_ipc4.c +++ b/src/audio/module_adapter/module/cadence_ipc4.c @@ -265,7 +265,14 @@ static int cadence_codec_init(struct processing_module *mod) setup_cfg->avail = true; codec->cfg.avail = false; - /* direction follows the codec params in init data */ + /* direction follows the codec params in init data; make sure the + * payload is large enough to hold it before dereferencing + */ + if (size < (int)(sizeof(struct snd_codec) + sizeof(uint32_t))) { + comp_err(dev, "setup config too small for direction: %d", size); + ret = -EINVAL; + goto free_cfg; + } init_bytes = (uint8_t *)ext_data->module_data; cd->direction = *(uint32_t *)(init_bytes + sizeof(struct snd_codec)); diff --git a/src/audio/module_adapter/module/waves/waves.c b/src/audio/module_adapter/module/waves/waves.c index d328d9e5167f..1727628cd482 100644 --- a/src/audio/module_adapter/module/waves/waves.c +++ b/src/audio/module_adapter/module/waves/waves.c @@ -612,6 +612,15 @@ static int waves_effect_apply_config(struct processing_module *mod) for (index = 0; index < cfg->size && (!ret); param_number++) { uint32_t param_data_size; + /* make sure a whole param header remains before reading + * param->size / param->id below + */ + if (index + header_size > cfg->size) { + comp_err(dev, "module_param header exceeds cfg buffer size: %d", + cfg->size); + return -EINVAL; + } + param = (struct module_param *)((char *)cfg->data + index); param_data_size = param->size - sizeof(param->size) - sizeof(param->id); diff --git a/src/audio/module_adapter/module_adapter_ipc3.c b/src/audio/module_adapter/module_adapter_ipc3.c index 74c8f02afa2f..66d312522410 100644 --- a/src/audio/module_adapter/module_adapter_ipc3.c +++ b/src/audio/module_adapter/module_adapter_ipc3.c @@ -184,21 +184,25 @@ static int module_adapter_get_set_params(struct comp_dev *dev, struct sof_ipc_ct const struct module_interface *const interface = mod->dev->drv->adapter_ops; enum module_cfg_fragment_position pos; uint32_t data_offset_size; - static uint32_t size; + /* per-instance reassembly size; a file-scope static would be shared + * across all module_adapter components and corrupted by interleaved + * fragmented transfers + */ + uint32_t *size = &mod->runtime_params_size; comp_dbg(dev, "num_of_elem %d, elem remain %d msg_index %u", cdata->num_elems, cdata->elems_remaining, cdata->msg_index); /* set the fragment position, data offset and config data size */ if (!cdata->msg_index) { - size = cdata->num_elems + cdata->elems_remaining; - data_offset_size = size; + *size = cdata->num_elems + cdata->elems_remaining; + data_offset_size = *size; if (cdata->elems_remaining) pos = MODULE_CFG_FRAGMENT_FIRST; else pos = MODULE_CFG_FRAGMENT_SINGLE; } else { - data_offset_size = size - (cdata->num_elems + cdata->elems_remaining); + data_offset_size = *size - (cdata->num_elems + cdata->elems_remaining); if (cdata->elems_remaining) pos = MODULE_CFG_FRAGMENT_MIDDLE; else diff --git a/src/include/module/module/base.h b/src/include/module/module/base.h index 657673099d60..8a8237666b16 100644 --- a/src/include/module/module/base.h +++ b/src/include/module/module/base.h @@ -118,6 +118,12 @@ struct processing_module { uint32_t deep_buff_bytes; /**< copy start threshold */ uint32_t output_buffer_size; /**< size of local buffer to save produced samples */ + /* total size of a fragmented runtime-params (get/set) transfer, kept + * per instance so concurrent transfers to different components do not + * corrupt each other's reassembly state + */ + uint32_t runtime_params_size; + /* number of sinks / sources and (when in use) input_buffers / input_buffers */ uint32_t num_of_sources; uint32_t num_of_sinks;