Audio: Fix the init() in modules to not initialize bytes control with invalid data#10646
Audio: Fix the init() in modules to not initialize bytes control with invalid data#10646singalsu wants to merge 4 commits intothesofproject:mainfrom
Conversation
This patch moves the configuration blob out of the IPC init message in create_eq_iir_comp_ipc(). It adds a new eq_iir_send_config() function that sends the blob via the module's set_configuration() callback and calls it from setup() after component creation. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
Move the configuration blob out of the IPC init message in create_eq_fir_comp_ipc(). Add a new eq_fir_send_config() function that sends the blob via the module's set_configuration() callback, and call it from setup() after component creation. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
f9b0c16 to
fc8e5cb
Compare
There was a problem hiding this comment.
Pull request overview
This PR adjusts how IPC4 testbench/topology and several audio modules handle bytes-control configuration blobs, preventing modules from attempting to initialize/apply invalid or absent binary data during init() and ensuring configuration is only applied when a valid blob exists.
Changes:
- Testbench IPC4: skip sending bytes controls when the parsed bytes payload is missing/too small to contain an ABI header.
- Modules: stop initializing data-blob handlers from
md->cfgduringinit()and instead gate configuration application inprepare()based on retrieved blob size. - Cmocka EQ tests: stop embedding coefficients in the component IPC creation and instead send configuration via
set_configuration()beforeprepare().
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tools/testbench/utils_ipc4.c | Avoids sending bytes-control IPC when ctl->data is NULL. |
| tools/testbench/topology_ipc4.c | Only assigns ctl->data for bytes controls when at least an ABI header is present. |
| test/cmocka/src/audio/eq_iir/eq_iir_process.c | Sends EQ IIR config via control path instead of embedding it into init IPC. |
| test/cmocka/src/audio/eq_fir/eq_fir_process.c | Sends EQ FIR config via control path instead of embedding it into init IPC. |
| src/audio/tdfb/tdfb.c | Removes init-time blob initialization; attempts to gate blob usage in prepare(). |
| src/audio/multiband_drc/multiband_drc.c | Removes init-time blob initialization; applies config only when a blob is present in prepare(). |
| src/audio/mfcc/mfcc.c | Removes init-time blob initialization; applies config only when a blob is present in prepare(). |
| src/audio/eq_iir/eq_iir.c | Removes init-time blob initialization; applies config only when a blob is present in prepare(). |
| src/audio/eq_fir/eq_fir.c | Removes init-time blob initialization; applies config only when a blob is present in prepare(). |
| src/audio/drc/drc.c | Removes init-time blob initialization; applies config only when a blob is present in prepare(). |
| src/audio/dcblock/dcblock.c | Removes init-time blob initialization; uses passthrough when no blob is present in prepare(). |
| src/audio/crossover/crossover.c | Removes init-time blob initialization; validates/applies config in prepare() when present, otherwise passthrough. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
fc8e5cb to
87fa65d
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…data The change in removing bytes control blob in module init() triggered an issue in sof-testbench4. It resulted in valgrind fail with scripts/host-testbench.sh run with error "Invalid read of size 1" in "memcpy(msg + sizeof(config), (char *)abi->data + offset, chunk_size)". The invalid read happens when abi->data doesn't have chunk_size bytes available. The fix is to skip bytes controls with no private data to avoid reading garbage abi->size from adjacent topology buffer data, which causes invalid memory reads in tb_send_bytes_data(). Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
The pass of bytes control blob from topology in init() was used in some early IPC3 kernels but with add of support for multiple controls blob it was changed to use normal controls IPC. With IPC4 the module configuration data is not for ALSA controls while some modules still handled it as such. If a topology does not contain a blob to initialize the control, an invalid blob is attempted to be used in prepare(). The prepare() then fails with invalid blob detected while the modules would normally result to pass-through mode when not configured. In addition to code removal a check is added to prepare() for the data_size from comp_get_data_blob() to ensure the configuration data is not zero size. This patch fixes the similar issue in crossover, dcblock, drc, fir, iir, mfcc, multiband-drc, and tdfb. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
87fa65d to
a7ffffa
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
src/audio/mfcc/mfcc.c:201
- In mfcc_prepare(), if the configuration blob is missing/empty then mfcc_setup() is skipped, but mfcc_process() will still call mfcc_s16_default() via cd->mfcc_func. mfcc_s16_default() uses fields/buffers initialized by mfcc_setup() (e.g., FFT plan/buffers), so proceeding without a valid blob risks NULL-deref or invalid memory access. Consider failing prepare() (e.g., -EINVAL) when no valid config is present, or explicitly switching to a safe “disabled” processing path that does not rely on mfcc_setup()-initialized state.
cd->config = comp_get_data_blob(cd->model_handler, &data_size, NULL);
/* Initialize MFCC, max_frames is set to dev->frames + 4 */
if (cd->config && data_size > 0) {
ret = mfcc_setup(mod, dev->frames + 4, audio_stream_get_rate(&sourceb->stream),
audio_stream_get_channels(&sourceb->stream));
if (ret < 0) {
comp_err(dev, "setup failed.");
goto err;
}
}
src/audio/multiband_drc/multiband_drc.c:378
- multiband_drc_prepare() currently continues when the config blob is missing/empty (cd->config == NULL or size == 0), but multiband_drc_process() will call cd->multiband_drc_func when process_enabled is true. The default multiband_drc_* processing functions dereference cd->config unconditionally (e.g., cd->config->num_bands), so running without a valid blob can crash. Suggest either failing prepare() when no blob is present, or forcing a safe bypass path when config is absent (e.g., set process_enabled=false and/or select the *_pass function map).
/* Initialize DRC */
comp_dbg(dev, "source_format=%d, sink_format=%d",
cd->source_format, cd->source_format);
cd->config = comp_get_data_blob(cd->model_handler, &data_size, NULL);
if (cd->config && data_size > 0) {
ret = multiband_drc_setup(mod, channels, rate);
if (ret < 0) {
comp_err(dev, "error: multiband_drc_setup failed.");
return ret;
}
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Note: Related kernel patch is thesofproject/linux#5708 . |
No description provided.