Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 28 additions & 11 deletions src/audio/module_adapter/module_adapter_ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <sof/audio/module_adapter/module/generic.h>
#include <sof/audio/pipeline.h>
#include <sof/common.h>
#include <sof/lib/mailbox.h>
#include <sof/platform.h>
#include <sof/ut.h>
#include <rtos/interrupt.h>
Expand All @@ -28,17 +29,22 @@ LOG_MODULE_DECLARE(module_adapter, CONFIG_SOF_LOG_LEVEL);
int module_ext_init_decode(const struct comp_driver *drv, struct module_ext_init_data *ext_data,
struct ipc_config_process *spec)
{
const struct ipc4_module_init_ext_init *ext_init =
(const struct ipc4_module_init_ext_init *)spec->data;
bool last_object = !ext_init->data_obj_array;
const struct ipc4_module_init_ext_init *ext_init;
const struct ipc4_module_init_ext_object *obj;
bool last_object;
size_t consumed;

assert(drv->type == SOF_COMP_MODULE_ADAPTER);
if (spec->size < sizeof(ext_init)) {
comp_cl_err(drv, "Size too small for ext init %zu < %zu",
spec->size, sizeof(ext_init));

/* Validate size before dereferencing ext_init pointer */
if (spec->size < sizeof(*ext_init)) {
comp_cl_err(drv, "Size too small for ext init %u < %zu",
spec->size, sizeof(*ext_init));
Comment thread
tmleman marked this conversation as resolved.
return -EINVAL;
}

ext_init = (const struct ipc4_module_init_ext_init *)spec->data;
last_object = !ext_init->data_obj_array;
/* TODO: Handle ext_init->gna_used and ext_init->rtos_domain here */
/* Get the first obj struct right after ext_init struct */
obj = (const struct ipc4_module_init_ext_object *)(ext_init + 1);
Expand All @@ -47,15 +53,15 @@ int module_ext_init_decode(const struct comp_driver *drv, struct module_ext_init

/* Check if there is space for the object header */
if ((unsigned char *)(obj + 1) - spec->data > spec->size) {
comp_cl_err(drv, "ext init obj overflow, %u > %zu",
comp_cl_err(drv, "ext init obj overflow, %u > %u",
(unsigned char *)(obj + 1) - spec->data, spec->size);
return -EINVAL;
}
/* Calculate would be next object position and check if current object fits */
next_obj = (const struct ipc4_module_init_ext_object *)
(((uint32_t *) (obj + 1)) + obj->object_words);
if ((unsigned char *)next_obj - spec->data > spec->size) {
comp_cl_err(drv, "ext init object array overflow, %u > %zu",
comp_cl_err(drv, "ext init object array overflow, %u > %u",
(unsigned char *)obj - spec->data, spec->size);
return -EINVAL;
}
Expand Down Expand Up @@ -102,8 +108,17 @@ int module_ext_init_decode(const struct comp_driver *drv, struct module_ext_init
obj = next_obj;
}

/* Remove decoded ext_init payload from spec */
spec->size -= (unsigned char *)obj - spec->data;
/*
* Remove decoded ext_init payload from spec.
* consumed <= spec->size is guaranteed here:
* - no-loop path: consumed == sizeof(*ext_init) <= spec->size (validated above)
* - loop path: in-loop bounds checks (obj/next_obj vs spec->size) ensure
* obj never advances past spec->data + spec->size
*/
consumed = (unsigned char *)obj - spec->data;
assert(consumed <= spec->size);

spec->size -= consumed;
spec->data = (const unsigned char *)obj;

return 0;
Expand Down Expand Up @@ -132,8 +147,10 @@ int module_adapter_init_data(struct comp_dev *dev,

if (cfg == NULL)
return -EINVAL;
if (cfgsz < sizeof(cfg->base_cfg))
if (cfgsz > MAILBOX_HOSTBOX_SIZE || cfgsz < sizeof(cfg->base_cfg)) {
comp_err(dev, "invalid config size %zu", cfgsz);
return -EINVAL;
}

dst->base_cfg = cfg->base_cfg;
dst->size = cfgsz;
Expand Down
Loading