Skip to content

audio: base_fw: validate dma control payload length before subtract#10888

Merged
lgirdwood merged 1 commit into
thesofproject:mainfrom
tmleman:topic/upstream/pr/ipc4/base_fw/dma_control/add_size_check
Jun 12, 2026
Merged

audio: base_fw: validate dma control payload length before subtract#10888
lgirdwood merged 1 commit into
thesofproject:mainfrom
tmleman:topic/upstream/pr/ipc4/base_fw/dma_control/add_size_check

Conversation

@tmleman

@tmleman tmleman commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

basefw_dma_control() computes data_size = data_offset - sizeof(struct ipc4_dma_control) where data_offset is the host-supplied payload length. When data_offset is smaller than the header the unsigned subtraction wraps to a huge value that passes the length check and is forwarded as the payload size, leading to an out-of-bounds read.

Reject data_offset values smaller than the fixed header before the subtraction.

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.

Pull request overview

This PR hardens IPC4 DMA Control handling in base_fw by validating the host-supplied payload length before computing the variable-sized payload portion, preventing unsigned wraparound that could lead to out-of-bounds reads.

Changes:

  • Add a minimum-length check to ensure data_offset covers struct ipc4_dma_control before subtracting the header size.
  • Return IPC4_ERROR_INVALID_PARAM (and log) when an undersized DMA Control message is received.
Comments suppressed due to low confidence (1)

src/audio/base_fw.c:786

  • The length comparison/logging uses dma_control->config_length * sizeof(uint32_t) which can overflow on 32-bit builds and let an undersized buffer pass the check. Also the current tr_err() uses %u for data_size (a size_t), which is undefined behavior and can print garbage. Prefer an overflow-safe comparison and %zu for size_t.
	if (data_size < (dma_control->config_length * sizeof(uint32_t))) {
		tr_err(&ipc_tr, "DMA Control data too short: got %u, expected %u",
		       data_size, dma_control->config_length);
		return IPC4_ERROR_INVALID_PARAM;
	}

basefw_dma_control() computes data_size = data_offset - sizeof(struct
ipc4_dma_control) where data_offset is the host-supplied payload
length. When data_offset is smaller than the header the unsigned
subtraction wraps to a huge value that passes the length check and is
forwarded as the payload size, leading to an out-of-bounds read.

Reject data_offset values smaller than the fixed header before the
subtraction.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
@lgirdwood lgirdwood merged commit bed995f into thesofproject:main Jun 12, 2026
45 checks passed
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