Skip to content

audio: mixin_mixout: reject prepare of an unconnected instance - #11180

Open
tmleman wants to merge 1 commit into
thesofproject:mainfrom
tmleman:topic/upstream/pr/audio/mixin_mixout/reject_ppl_state_change_with_no_buffer
Open

audio: mixin_mixout: reject prepare of an unconnected instance#11180
tmleman wants to merge 1 commit into
thesofproject:mainfrom
tmleman:topic/upstream/pr/audio/mixin_mixout/reject_ppl_state_change_with_no_buffer

Conversation

@tmleman

@tmleman tmleman commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

mixin_prepare() and mixout_prepare() dereferenced sinks[0] without checking num_of_sinks. The connection arrays in struct processing_module are only populated by module_adapter_bind(), and
module_adapter_sink_src_prepare() forwards them verbatim, so a module instance that the host created but never bound is still prepared with num_of_sinks == 0 and sinks[0] == NULL.

A host that issues CREATE_PIPELINE, INIT_MODULE_INSTANCE (mixin/mixout) and then SET_PIPELINE_STATE without any BIND therefore made pipeline_prepare() walk into mixout_params(), where sink_set_valid_fmt(mod->sinks[0], ...) faulted while writing sink->audio_stream_params (SEGV on NULL + 0x14). mixin_prepare() has the same unguarded sink_get_valid_fmt(sinks[0]) one function later; both are fixed here.

Reject an instance with no sink in .prepare() with -ENOTCONN before the dereference, matching the existing guards in rtnr_prepare() and mux_process(). This cannot reject a valid configuration: a functional mixin/mixout must have at least one bound sink. The mixout_prepare() entry trace is moved above the check so the rejected case is traced too.

Found by the IPC4 libFuzzer harness on native_sim under ASan.

Copilot AI lite review requested due to automatic review settings September 9, 2026 06:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The added guards correctly prevent confirmed NULL-dereference paths for unbound instances and follow established module behavior by returning -ENOTCONN.

Pull request overview

This pull request prevents NULL dereferences in the mixin/mixout modules when a host prepares an instance that was created but never bound (no sink connections), by rejecting .prepare() early with -ENOTCONN. This aligns mixin_prepare()/mixout_prepare() behavior with existing “unconnected instance” guards used by other SOF modules.

Changes:

  • Add an early num_of_sinks == 0 guard in mixin_prepare() before dereferencing sinks[0].
  • Add an early num_of_sinks == 0 guard in mixout_prepare() before calling mixout_params() (which dereferences mod->sinks[0]).
  • Move mixout_prepare() entry trace before the new guard so the rejected case is still logged.
File summaries
File Description
src/audio/mixin_mixout/mixin_mixout.c Adds -ENOTCONN prepare-time rejection for unconnected mixin/mixout instances to avoid sink dereferences when num_of_sinks == 0.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@intel-sofci

Copy link
Copy Markdown

PR 11180: test results

Run date: 2026-09-09 07:01 UTC

Tested commit: fc0d6b61757bdfaf9c99fdd609a2fcd72cbf28de

mtl pass rate lnl pass rate ptl pass rate wcl pass rate nvl pass rate

mixin_prepare() and mixout_prepare() dereferenced sinks[0] without
checking num_of_sinks. The connection arrays in struct processing_module
are only populated by module_adapter_bind(), and
module_adapter_sink_src_prepare() forwards them verbatim, so a module
instance that the host created but never bound is still prepared with
num_of_sinks == 0 and sinks[0] == NULL.

A host that issues CREATE_PIPELINE, INIT_MODULE_INSTANCE (mixin/mixout)
and then SET_PIPELINE_STATE without any BIND therefore made
pipeline_prepare() walk into mixout_params(), where
sink_set_valid_fmt(mod->sinks[0], ...) faulted while writing
sink->audio_stream_params (SEGV on NULL + 0x14). mixin_prepare() has the
same unguarded sink_get_valid_fmt(sinks[0]) one function later; both are
fixed here.

Reject an instance with no sink in .prepare() with -ENOTCONN before the
dereference, matching the existing guards in rtnr_prepare() and
mux_process(). This cannot reject a valid configuration: a functional
mixin/mixout must have at least one bound sink. The mixout_prepare()
entry trace is moved above the check so the rejected case is traced too.

Found by the IPC4 libFuzzer harness on native_sim under ASan.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants