Skip to content

ipc3: handler: pass control payload capacity to comp_cmd - #11237

Open
tmleman wants to merge 2 commits into
thesofproject:mainfrom
tmleman:topic/upstream/pr/ipc3/handler/pass_payload_capacity
Open

tmleman wants to merge 2 commits into
thesofproject:mainfrom
tmleman:topic/upstream/pr/ipc3/handler/pass_payload_capacity

Conversation

@tmleman

@tmleman tmleman commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

ipc_comp_value() handed SOF_IPC_MSG_MAX_SIZE, the size of the whole comp_data buffer, to comp_cmd() as max_data_size. Every IPC3 binary control "get" handler uses that value as the memcpy_s() destination size for cdata->data->data, which sits behind struct sof_ipc_ctrl_data and struct sof_abi_hdr (~120 bytes into comp_data). The claimed destination therefore extended past the end of the allocation.

Two consequences:

  • memcpy_s() checks the source against [dest, dest + dest_size). On native_sim comp_data and component private data share one heap, so a copy source located right after comp_data landed inside the phantom window and memcpy_s() returned -EINVAL for a copy that never overlapped. The handlers assert(!ret), turning it into a panic during IPC3 fuzzing.
  • A getter copying close to max_data_size bytes (comp_data_blob_get_cmd() with a large blob) could write up to the header size past comp_data.

Fix it at the single IPC3 entry point: pass the capacity remaining after the two headers. All comp_cmd() consumers already treat max_data_size as payload capacity, so no component changes are needed.

module_adapter's IPC3 get path passed cdata->num_elems as fragment_size instead of the buffer size, which made the getters' num_elems bound check a comparison of num_elems with itself and let the host request more than comp_data can hold. Forward max_data_size instead.

ipc_comp_value() handed SOF_IPC_MSG_MAX_SIZE, the size of the whole
comp_data buffer, to comp_cmd() as max_data_size. Every IPC3 binary
control "get" handler uses that value as the memcpy_s() destination size
for cdata->data->data, which sits behind struct sof_ipc_ctrl_data and
struct sof_abi_hdr (~120 bytes into comp_data). The claimed destination
therefore extended past the end of the allocation.

Two consequences:

- memcpy_s() checks the source against [dest, dest + dest_size). On
  native_sim comp_data and component private data share one heap, so a
  copy source located right after comp_data landed inside the phantom
  window and memcpy_s() returned -EINVAL for a copy that never overlapped.
  The handlers assert(!ret), turning it into a panic during IPC3 fuzzing.

- A getter copying close to max_data_size bytes (comp_data_blob_get_cmd()
  with a large blob) could write up to the header size past comp_data.

Fix it at the single IPC3 entry point: pass the capacity remaining after
the two headers. All comp_cmd() consumers already treat max_data_size as
payload capacity, so no component changes are needed.

module_adapter's IPC3 get path passed cdata->num_elems as fragment_size
instead of the buffer size, which made the getters' num_elems bound check
a comparison of num_elems with itself and let the host request more than
comp_data can hold. Forward max_data_size instead.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
test_keyword_get_config() copies cd->config.size bytes out of the
fixed-size cd->config. The size field is taken verbatim from the blob:
the IPC3 set path checks it against sizeof(struct sof_detect_test_config)
but the topology init path in test_keyword_new() only requires the blob
to be at least that large, so the embedded size field can be arbitrary.
A subsequent SOF_IPC_COMP_GET_DATA then reads past cd->config, up to the
reply buffer capacity, and returns adjacent heap contents to the host.

Bound bs by sizeof(cd->config) as smart_amp_get_config() already does.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
@lgirdwood

Copy link
Copy Markdown
Member

I think we've both fixed this, will close my draft PR.

@tmleman
tmleman marked this pull request as ready for review September 28, 2026 07:42
Copilot AI lite review requested due to automatic review settings September 28, 2026 07:42

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.

Copilot review overview

🟢 Approval recommended

The reviewed changes address IPC3 payload bounds without unresolved blocking issues.

Review effort: Lite
Findings: None

What changed in this PR

Fixes IPC3 control getter buffer sizing to prevent false overlap errors and out-of-bounds writes.

Changes:

  • Passes payload capacity after IPC headers to component handlers.
  • Corrects module adapter getter sizing.
  • Bounds detect-test configuration copies.
File Description
src/​samples/​audio/​detect_test.c Validates configuration source size.
src/​ipc/​ipc3/​handler.c Computes safe control payload capacity.
src/​audio/​module_adapter/​module_adapter_ipc3.c Forwards corrected getter capacity.

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

@lgirdwood

lgirdwood commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

@tmleman just 1 CI open, not sure if tested anyway on failing CI ?

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.

4 participants