Repository navigation
audio: crossover: validate config blobs at IPC time - #11385
Shrusti-pk wants to merge 1 commit into
Conversation
|
Can one of the admins verify this patch?
|
|
@Shrusti-pk missing sob, btw you should be able to start running modules on testbench now. See new sof-utils repo. |
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues were identified for the changes that validate crossover blobs before replacing the active configuration.
No open issues 🎉
What changed in this PR
This PR moves crossover blob validation to IPC time, rejecting malformed configurations and unsupported sink-count changes before they replace the active configuration.
Changes:
- Adds an IPC-time validator for blob size and sink count, while retaining sink-assignment checks in prepare and process.
- Removes the unsafe process-time rollback to the freed previous configuration.
- Adds native_sim regression tests for rejected updates and valid same-count updates.
| File | Description |
|---|---|
test/ztest/unit/audio/crossover_blob/testcase.yaml |
Registers the native_sim crossover blob test suite. |
test/ztest/unit/audio/crossover_blob/prj.conf |
Enables crossover and audio-format support for testing. |
test/ztest/unit/audio/crossover_blob/crossover_blob_ztest.c |
Tests update rejection, configuration preservation, and valid updates. |
test/ztest/unit/audio/crossover_blob/CMakeLists.txt |
Builds the suite with crossover, blob-handler, and module-adapter code. |
src/audio/crossover/crossover.c |
Adds IPC-time validation and removes unsafe configuration rollback. |
Review effort: Balanced
kv2019i
left a comment
There was a problem hiding this comment.
Signed-off is missing, but code looks good and fixes a real bug.
crossover_process() fetches a new config with comp_get_data_blob(), which frees the blob in use, and validates it only afterwards. A blob that fails validation stays in cd->config, and one refused for changing num_sinks restores prev_config, which has just been freed. An LL pipeline stops on the error and prepare reloads cd->config, but dp_task_run() ignores the error and calls process again, so a DP instance runs with the bad pointer. An out of range num_sinks then indexes past the assigned_sinks[] stack array, and a 3-way to 2-way update reads the freed blob. Only a smaller count reaches the freed path, as crossover_check_sink_assign() stops at the first sink the blob does not name. Move the size and num_sinks checks to a blob validator, as drc, eq_iir, eq_fir, tdfb and multiband_drc do, so a bad blob is refused with -EINVAL while the current one is intact. A num_sinks change is refused there too, by comparing against the split function in use. The sink assignment check stays in prepare and process, as it needs the sinks connected. Add a ztest running the module on the real data blob handler. Signed-off-by: Shrushti P K <shrusthi@labs.digiscrypt.com>
c27f2c5 to
db1559b
Compare
|
Sign-off added, the commit is otherwise unchanged. I'll look at sof-utils and try running crossover on the testbench there, as the ztest only covers the IPC3 plumbing and a real stream through the module would be a better check of the update path. |
crossover_process() gets a run-time config with comp_get_data_blob(), which frees the blob in use, and only then validates it, so a rejected blob has nothing to fall back to. A blob that fails validation stays in cd->config, and one that only fails the num_sinks change check puts back prev_config, which was just freed. On an LL pipeline the error resets the pipeline and prepare reloads cd->config, so that case is a stopped stream and a lost config. dp_task_run() ignores the error and reschedules, so a DP instance runs process again with the bad pointer. No in-tree topology puts crossover on DP, but scheduler_domain can, and the firmware does not check proc_domain against the manifest domain_types. I reproduced both in a native_sim ASan build by calling the process op twice, as dp_task_run() would: num_sinks = 8 gives a stack-buffer-overflow in crossover_assign_sinks() on the 4 entry assigned_sinks[], and a valid 3-way to 2-way update gives a heap-use-after-free in crossover_get_stream_index(). Only a smaller count reaches the freed path, because crossover_check_sink_assign() stops at the first sink the blob does not name. A blob validator now refuses both at IPC time while the current blob is intact, so the host gets -EINVAL and the stream keeps running, the same way drc, eq_iir and tdfb handle it. The sink assignment check stays in prepare and process because it needs the sinks connected. The new crossover_blob ztest fails on the old code, the ztest job and the IPC4 testbench build pass, and the six 2, 3 and 4-way blobs in tree pass the same size and num_sinks rules. The test uses the IPC3 plumbing like the drc suite, crossover_process() is shared with IPC4, and none of this has been run on hardware.