From 31590ac8f0da55f169c5d86df3c9c5c4661c4427 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Thu, 11 Jun 2026 14:30:37 +0100 Subject: [PATCH 1/3] volume: avoid use-after-free in init error path On an invalid ramp type the init error path freed the component data then read a field from it. Free the dependent allocation before the component data and stop dereferencing it afterwards. Signed-off-by: Liam Girdwood --- src/audio/volume/volume_ipc3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/volume/volume_ipc3.c b/src/audio/volume/volume_ipc3.c index 6a88b68e6ae8..053b41e32152 100644 --- a/src/audio/volume/volume_ipc3.c +++ b/src/audio/volume/volume_ipc3.c @@ -157,8 +157,8 @@ int volume_init(struct processing_module *mod) break; default: comp_err(dev, "invalid ramp type %d", vol->ramp); - mod_free(mod, cd); mod_free(mod, cd->vol); + mod_free(mod, cd); return -EINVAL; } From 2078f8bc0b5e920dfc484a8a3004481fb7beb6ea Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Thu, 11 Jun 2026 14:32:42 +0100 Subject: [PATCH 2/3] volume: validate init payload covers per-channel config Init read a per-channel config array sized by the channel count from the init payload without checking the payload was large enough, reading past the mailbox. Require the payload to cover the base config and all per-channel entries. Signed-off-by: Liam Girdwood --- src/audio/volume/volume_ipc4.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/audio/volume/volume_ipc4.c b/src/audio/volume/volume_ipc4.c index 57a5f427903e..a1e6e6eff25f 100644 --- a/src/audio/volume/volume_ipc4.c +++ b/src/audio/volume/volume_ipc4.c @@ -127,6 +127,15 @@ int volume_init(struct processing_module *mod) return -EINVAL; } + /* the per-channel config[] array is read below for every channel, so + * the init payload must be large enough to hold them all + */ + if (cfg->size < sizeof(*vol) + channels_count * sizeof(vol->config[0])) { + comp_err(dev, "Invalid init payload size %zu for %u channels", + cfg->size, channels_count); + return -EINVAL; + } + cd = mod_zalloc(mod, sizeof(struct vol_data)); if (!cd) return -ENOMEM; From 24e5f5eb35119d8268de638ddda258428f9fcb2c Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Thu, 11 Jun 2026 14:32:42 +0100 Subject: [PATCH 3/3] volume: require a full word for the attenuation control The attenuation setter only rejected oversized payloads, then dereferenced the data as a 32-bit value; a shorter payload read past the mailbox. Require exactly a 32-bit payload. Signed-off-by: Liam Girdwood --- src/audio/volume/volume_ipc4.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/audio/volume/volume_ipc4.c b/src/audio/volume/volume_ipc4.c index a1e6e6eff25f..d444c2257f0a 100644 --- a/src/audio/volume/volume_ipc4.c +++ b/src/audio/volume/volume_ipc4.c @@ -277,8 +277,10 @@ static int volume_set_attenuation(struct processing_module *mod, const uint8_t * struct comp_dev *dev = mod->dev; uint32_t attenuation; - /* only support attenuation in format of 32bit */ - if (data_size > sizeof(uint32_t)) { + /* only support attenuation in format of 32bit; the payload is + * dereferenced as a uint32_t below so it must be exactly that size + */ + if (data_size != (int)sizeof(uint32_t)) { comp_err(dev, "attenuation data size %d is incorrect", data_size); return -EINVAL; }