Skip to content

Commit 20c85b6

Browse files
committed
audio: drc: register IPC-time blob validator
Hook a drc blob validator into the model handler so a corrupted run-time configuration update is rejected before it can replace the working blob. Playback or capture then continues with the previously set parameters instead of being interrupted by a bad IPC. The DRC configuration is a fixed-size struct sof_drc_config, so the validator requires the IPC payload size to match exactly and the self-declared config->size to agree with it. The same size check is also reused at prepare time when the initial blob is fetched. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent e87b9af commit 20c85b6

1 file changed

Lines changed: 38 additions & 3 deletions

File tree

src/audio/drc/drc.c

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,34 @@ static int drc_setup(struct processing_module *mod, uint16_t channels, uint32_t
139139
return drc_set_pre_delay_time(&cd->state, cd->config->params.pre_delay_time, rate);
140140
}
141141

142+
static int drc_check_blob_size(struct comp_dev *dev, size_t size)
143+
{
144+
if (size != sizeof(struct sof_drc_config)) {
145+
comp_err(dev, "invalid configuration blob, size %zu", size);
146+
return -EINVAL;
147+
}
148+
149+
return 0;
150+
}
151+
152+
static int drc_validator(struct comp_dev *dev, void *new_data, uint32_t new_data_size)
153+
{
154+
struct sof_drc_config *config = new_data;
155+
int ret;
156+
157+
ret = drc_check_blob_size(dev, new_data_size);
158+
if (ret < 0)
159+
return ret;
160+
161+
if (config->size != new_data_size) {
162+
comp_err(dev, "blob size %u / header size %u mismatch",
163+
new_data_size, config->size);
164+
return -EINVAL;
165+
}
166+
167+
return 0;
168+
}
169+
142170
/*
143171
* End of DRC setup code. Next the standard component methods.
144172
*/
@@ -353,10 +381,10 @@ static int drc_prepare(struct processing_module *mod,
353381
/* Initialize DRC */
354382
comp_info(dev, "source_format=%d", cd->source_format);
355383
cd->config = comp_get_data_blob(cd->model_handler, &data_size, NULL);
356-
/* the blob is dereferenced as a struct sof_drc_config below and in
357-
* drc_setup(), so require it to be at least that large
384+
/* The blob is dereferenced as a struct sof_drc_config below and in
385+
* drc_setup(), so size-check it before use.
358386
*/
359-
if (cd->config && data_size >= sizeof(struct sof_drc_config)) {
387+
if (cd->config && drc_check_blob_size(dev, data_size) == 0) {
360388
ret = drc_setup(mod, channels, rate);
361389
if (ret < 0) {
362390
comp_err(dev, "error: drc_setup failed.");
@@ -382,6 +410,11 @@ static int drc_prepare(struct processing_module *mod,
382410
cd->drc_func = drc_default_pass;
383411
}
384412

413+
/* Reject malformed blobs at IPC time so a bad run-time update cannot
414+
* replace the working configuration.
415+
*/
416+
comp_data_blob_set_validator(cd->model_handler, drc_validator);
417+
385418
comp_info(dev, "DRC is configured.");
386419
return 0;
387420
}
@@ -390,6 +423,8 @@ static int drc_reset(struct processing_module *mod)
390423
{
391424
struct drc_comp_data *cd = module_get_private_data(mod);
392425

426+
comp_data_blob_set_validator(cd->model_handler, NULL);
427+
393428
drc_reset_state(mod, &cd->state);
394429

395430
return 0;

0 commit comments

Comments
 (0)