mirror of
https://github.com/torvalds/linux.git
synced 2026-09-13 15:40:03 +02:00
ASoC: Intel: avs: Refactor and fix init_config access
Existing code accesses enties found in ->init_configs array through
indexes that are part of ->config_ids array. Those two are limited by:
->num_init_configs and ->num_config_ids respectively. Using ID larger
or equal to ->num_init_configs leads to out-of-bounds access:
avs_path_module_send_init_configs()
loop:
(...) &acomp->tplg->init_configs[ids[i]]
^ out-of-bounds candidate
Rather than adding another if-statement, refactor the code. There is no
need to store the IDs, have a list of pointers to actual config-entries
instead. As the verification of ->init_config entries does not differ from
verification of other types that are part of the topology.c file, simply
reuse the code.
Fixes: 8a49ef789b ("ASoC: Intel: avs: Send initial config to module if present")
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://patch.msgid.link/20260902081814.1590883-10-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
d4fa6f94b9
commit
681e91035d
|
|
@ -836,15 +836,10 @@ static int avs_path_module_type_create(struct avs_dev *adev, struct avs_path_mod
|
|||
|
||||
static int avs_path_module_send_init_configs(struct avs_dev *adev, struct avs_path_module *mod)
|
||||
{
|
||||
struct avs_soc_component *acomp;
|
||||
struct avs_tplg_module *template = mod->template;
|
||||
|
||||
acomp = to_avs_soc_component(mod->template->owner->owner->owner->owner->comp);
|
||||
|
||||
u32 num_ids = mod->template->num_config_ids;
|
||||
u32 *ids = mod->template->config_ids;
|
||||
|
||||
for (int i = 0; i < num_ids; i++) {
|
||||
struct avs_tplg_init_config *config = &acomp->tplg->init_configs[ids[i]];
|
||||
for (int i = 0; i < template->num_init_configs; i++) {
|
||||
struct avs_tplg_init_config *config = template->init_configs[i];
|
||||
size_t len = config->length;
|
||||
void *data = config->data;
|
||||
u32 param = config->param;
|
||||
|
|
|
|||
|
|
@ -350,6 +350,7 @@ AVS_DEFINE_PTR_PARSER(modcfg_base, struct avs_tplg_modcfg_base, modcfgs_base);
|
|||
AVS_DEFINE_PTR_PARSER(modcfg_ext, struct avs_tplg_modcfg_ext, modcfgs_ext);
|
||||
AVS_DEFINE_PTR_PARSER(pplcfg, struct avs_tplg_pplcfg, pplcfgs);
|
||||
AVS_DEFINE_PTR_PARSER(binding, struct avs_tplg_binding, bindings);
|
||||
AVS_DEFINE_PTR_PARSER(init_config, struct avs_tplg_init_config, init_configs);
|
||||
AVS_DEFINE_PTR_PARSER(nhlt_config, struct avs_tplg_nhlt_config, nhlt_configs);
|
||||
|
||||
static int
|
||||
|
|
@ -1198,7 +1199,7 @@ static const struct avs_tplg_token_parser module_parsers[] = {
|
|||
{
|
||||
.token = AVS_TKN_MOD_INIT_CONFIG_NUM_IDS_U32,
|
||||
.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
|
||||
.offset = offsetof(struct avs_tplg_module, num_config_ids),
|
||||
.offset = offsetof(struct avs_tplg_module, num_init_configs),
|
||||
.parse = avs_parse_byte_token,
|
||||
},
|
||||
{
|
||||
|
|
@ -1214,10 +1215,32 @@ static const struct avs_tplg_token_parser init_config_parsers[] = {
|
|||
.token = AVS_TKN_MOD_INIT_CONFIG_ID_U32,
|
||||
.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
|
||||
.offset = 0,
|
||||
.parse = avs_parse_word_token,
|
||||
.parse = avs_parse_init_config_ptr,
|
||||
},
|
||||
};
|
||||
|
||||
static int avs_tplg_module_init_configs(struct snd_soc_component *comp,
|
||||
struct avs_tplg_module *module,
|
||||
struct snd_soc_tplg_vendor_array *tuples, u32 block_size)
|
||||
{
|
||||
struct avs_tplg_init_config **cfgs;
|
||||
int ret;
|
||||
|
||||
if (!module->num_init_configs)
|
||||
return -EINVAL;
|
||||
|
||||
cfgs = devm_kcalloc(comp->card->dev, module->num_init_configs, sizeof(*cfgs), GFP_KERNEL);
|
||||
if (!cfgs)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = parse_dictionary_entries(comp, tuples, block_size, cfgs, module->num_init_configs,
|
||||
sizeof(*cfgs), AVS_TKN_MOD_INIT_CONFIG_ID_U32,
|
||||
init_config_parsers, ARRAY_SIZE(init_config_parsers));
|
||||
if (!ret)
|
||||
module->init_configs = cfgs;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct avs_tplg_module *
|
||||
avs_tplg_module_create(struct snd_soc_component *comp, struct avs_tplg_pipeline *owner,
|
||||
struct snd_soc_tplg_vendor_array *tuples, u32 block_size)
|
||||
|
|
@ -1244,27 +1267,11 @@ avs_tplg_module_create(struct snd_soc_component *comp, struct avs_tplg_pipeline
|
|||
block_size -= esize;
|
||||
/* Parse trailing config ids if any. */
|
||||
if (block_size) {
|
||||
u32 num_config_ids = module->num_config_ids;
|
||||
u32 *config_ids;
|
||||
|
||||
if (!num_config_ids)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
config_ids = devm_kcalloc(comp->card->dev, num_config_ids, sizeof(*config_ids),
|
||||
GFP_KERNEL);
|
||||
if (!config_ids)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
tuples = avs_tplg_vendor_array_at(tuples, esize);
|
||||
ret = parse_dictionary_entries(comp, tuples, block_size,
|
||||
config_ids, num_config_ids, sizeof(*config_ids),
|
||||
AVS_TKN_MOD_INIT_CONFIG_ID_U32,
|
||||
init_config_parsers,
|
||||
ARRAY_SIZE(init_config_parsers));
|
||||
|
||||
ret = avs_tplg_module_init_configs(comp, module, tuples, block_size);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
module->config_ids = config_ids;
|
||||
}
|
||||
|
||||
module->owner = owner;
|
||||
|
|
|
|||
|
|
@ -221,8 +221,8 @@ struct avs_tplg_module {
|
|||
u8 domain;
|
||||
struct avs_tplg_modcfg_ext *cfg_ext;
|
||||
u32 ctl_id;
|
||||
u32 num_config_ids;
|
||||
u32 *config_ids;
|
||||
u32 num_init_configs;
|
||||
struct avs_tplg_init_config **init_configs;
|
||||
struct avs_tplg_nhlt_config *nhlt_config;
|
||||
|
||||
struct avs_tplg_pipeline *owner;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user