Skip to content

Commit 8ee41d7

Browse files
committed
audio: copier: bound ALH mapping count to the gateway config size
copier_alh_assign_dai_index() reads alh_cfg.count from the host-supplied gateway config blob and walks alh_cfg.mapping[0..count). count is only clamped to the mapping[] array size (IPC4_ALH_MAX_NUMBER_OF_GTW), never to the actual blob size, so a blob that advertises more mappings than it holds makes the walk read past the config_data allocation. The same unchecked count also underflows dma_config_length in the HDA branch (config_length * 4 - get_alh_config_size()). A fuzzer-crafted IPC4 copier init (config_length=13 -> 52-byte blob, count=15 -> 128 bytes needed) triggers a heap out-of-bounds read reported by AddressSanitizer at the SOF_DAI_INTEL_ALH mapping[] load. Validate up front that the blob holds the fixed header (so count can be read safely), that count is within the array bound, and that get_alh_config_size() fits in the blob before touching mapping[]. Valid ALH/HDA blobs are unaffected. This completes the earlier count guards by bounding count against the actual blob size. Also reject a gateway blob shorter than the fixed ALH header before reading or logging alh_cfg.count. Although the original compound check short-circuited the count validation safely, its error message still dereferenced count for a truncated blob. Capture and report count only after the header-size check succeeds. Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
1 parent ec86f80 commit 8ee41d7

1 file changed

Lines changed: 17 additions & 1 deletion

File tree

‎src/audio/copier/copier_dai.c‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,30 @@ static int copier_alh_assign_dai_index(struct comp_dev *dev,
7777
struct copier_data *cd = module_get_private_data(mod);
7878
const struct sof_alh_configuration_blob *alh_blob = gtw_cfg_data;
7979
uint8_t *dma_config;
80-
size_t alh_cfg_size, dma_config_length;
80+
size_t alh_cfg_size, dma_config_length, blob_size;
81+
uint32_t alh_count;
8182
int i, dai_num, ret;
8283

8384
if (!cd->config.gtw_cfg.config_length) {
8485
comp_err(mod->dev, "No gateway config found in blob!");
8586
return -EINVAL;
8687
}
8788

89+
blob_size = (size_t)cd->config.gtw_cfg.config_length << 2;
90+
if (blob_size < sizeof(alh_blob->gtw_attributes) + sizeof(alh_blob->alh_cfg.count)) {
91+
comp_err(mod->dev, "Invalid ALH gateway config: blob=%u bytes",
92+
(uint32_t)blob_size);
93+
return -EINVAL;
94+
}
95+
96+
alh_count = alh_blob->alh_cfg.count;
97+
if (alh_count > IPC4_ALH_MAX_NUMBER_OF_GTW ||
98+
get_alh_config_size(alh_blob) > blob_size) {
99+
comp_err(mod->dev, "Invalid ALH gateway config: count=%u, blob=%u bytes",
100+
alh_count, (uint32_t)blob_size);
101+
return -EINVAL;
102+
}
103+
88104
switch (dai->type) {
89105
case SOF_DAI_INTEL_HDA:
90106
/* We use DAI_INTEL_HDA for ACE 2.0 platforms */

0 commit comments

Comments
 (0)