From 3c5166686c34cf721248e6575f8a99ab5c7d40a0 Mon Sep 17 00:00:00 2001 From: Adrian Bonislawski Date: Fri, 12 Jun 2026 12:51:07 +0200 Subject: [PATCH 1/2] audio: copier: validate channels_count in copier_set_gain channels is host-controlled (8-bit, 0-255). Without validation it drives the memcpy length (channels * sizeof(uint16_t)) against a MAX_GAIN_COEFFS_CNT-sized stack buffer and, for channels == 0, causes divide-by-zero in the coefficient replication loop. Reject values outside [1, MAX_GAIN_COEFFS_CNT]. Signed-off-by: Adrian Bonislawski --- src/audio/copier/copier_gain.c | 9 +++++++-- src/audio/copier/copier_gain.h | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/audio/copier/copier_gain.c b/src/audio/copier/copier_gain.c index fc9f6664add8..fbf614fa3dde 100644 --- a/src/audio/copier/copier_gain.c +++ b/src/audio/copier/copier_gain.c @@ -150,7 +150,7 @@ int copier_gain_dma_control(union ipc4_connector_node_id node, const char *confi } struct ipc4_copier_module_cfg *copier_cfg = cd->dd[0]->dai_spec_config; - const int channels = copier_cfg->base.audio_fmt.channels_count; + const uint32_t channels = copier_cfg->base.audio_fmt.channels_count; ret = copier_set_gain(dev, cd->dd[0]->gain_data, gain_data, channels); if (ret) @@ -162,7 +162,7 @@ int copier_gain_dma_control(union ipc4_connector_node_id node, const char *confi } int copier_set_gain(struct comp_dev *dev, struct copier_gain_params *gain_params, - struct gain_dma_control_data *gain_data, int channels) + struct gain_dma_control_data *gain_data, uint32_t channels) { uint16_t static_gain[MAX_GAIN_COEFFS_CNT]; int ret; @@ -172,6 +172,11 @@ int copier_set_gain(struct comp_dev *dev, struct copier_gain_params *gain_params return -EINVAL; } + if (channels == 0 || channels > MAX_GAIN_COEFFS_CNT) { + comp_err(dev, "invalid channels count %u", channels); + return -EINVAL; + } + /* Set gain coefficients */ comp_info(dev, "Update gain coefficients from DMA_CONTROL ipc"); diff --git a/src/audio/copier/copier_gain.h b/src/audio/copier/copier_gain.h index ec55ff999206..bd7cc5719f5b 100644 --- a/src/audio/copier/copier_gain.h +++ b/src/audio/copier/copier_gain.h @@ -8,6 +8,7 @@ #ifndef __SOF_COPIER_GAIN_H__ #define __SOF_COPIER_GAIN_H__ +#include #include #include #include @@ -219,7 +220,7 @@ enum copier_gain_state copier_gain_eval_state(struct copier_gain_params *gain_pa * @return 0 on success, otherwise a negative error code. */ int copier_set_gain(struct comp_dev *dev, struct copier_gain_params *gain_params, - struct gain_dma_control_data *gain_data, int channels); + struct gain_dma_control_data *gain_data, uint32_t channels); /** * Checks for unity gain mode. From 466596f02b6f46ab41dd03f7ade179e33d7ebc25 Mon Sep 17 00:00:00 2001 From: Adrian Bonislawski Date: Fri, 12 Jun 2026 12:51:25 +0200 Subject: [PATCH 2/2] audio: copier: fix memcpy_s dest_size in copier_set_gain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first memcpy_s call passed gain_coef_size (= channels * sizeof(uint16_t), host-controlled) as the dest_size argument, defeating the bounds check. Pass sizeof(static_gain) — the true buffer capacity so memcpy_s can enforce the limit. Signed-off-by: Adrian Bonislawski --- src/audio/copier/copier_gain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/copier/copier_gain.c b/src/audio/copier/copier_gain.c index fbf614fa3dde..842f92997108 100644 --- a/src/audio/copier/copier_gain.c +++ b/src/audio/copier/copier_gain.c @@ -182,7 +182,7 @@ int copier_set_gain(struct comp_dev *dev, struct copier_gain_params *gain_params size_t gain_coef_size = channels * sizeof(uint16_t); - ret = memcpy_s(static_gain, gain_coef_size, gain_data->gain_coeffs, + ret = memcpy_s(static_gain, sizeof(static_gain), gain_data->gain_coeffs, gain_coef_size); if (ret) { comp_err(dev, "memcpy_s failed with error %d", ret);