[PATCH] ASoC: topology: Fix bounds check for widget private data
Naveed Khan <[email protected]> Tue, 23 Jun 2026 22:43:22 +0530
| Newsgroups | org.alsa-project.alsa-devel |
|---|---|
| Message-ID | <[email protected]> |
soc_tplg_dapm_widget_elems_load() validates that a DAPM widget fits within the topology firmware buffer before parsing it. The check for the widget header correctly accounts for sizeof(*widget): if (soc_tplg_get_offset(tplg) + sizeof(*widget) >= tplg->fw->size) but the subsequent check for the widget's private data only adds priv.size: if (soc_tplg_get_offset(tplg) + le32_to_cpu(widget->priv.size) >= tplg->fw->size) The private data is located after the widget header, and soc_tplg_dapm_widget_create() advances tplg->pos by sizeof(struct snd_soc_tplg_dapm_widget) + priv.size accordingly. Since the check omits the header size, a topology blob whose priv.size satisfies offset + priv.size < fw->size but offset + sizeof(*widget) + priv.size >= fw->size passes validation and leaves tplg->pos pointing past the end of the firmware buffer. When the widget declares one or more kcontrols, the following read of control_hdr->type dereferences memory up to sizeof(struct snd_soc_tplg_dapm_widget) bytes beyond the allocation, an out-of-bounds read whose length is controlled by the (firmware supplied) topology data. Include sizeof(*widget) in the private data bounds check, matching the widget header check above. Signed-off-by: Naveed Khan <[email protected]> --- diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 35cbe29d22..3f8bdacc3a 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -1290,7 +1290,8 @@ static int soc_tplg_dapm_widget_elems_load(struct soc_tplg *tplg, } /* check if widget private data fits within topology file */ - if (soc_tplg_get_offset(tplg) + le32_to_cpu(widget->priv.size) >= tplg->fw->size) { + if (soc_tplg_get_offset(tplg) + sizeof(*widget) + + le32_to_cpu(widget->priv.size) >= tplg->fw->size) { dev_err(tplg->dev, "ASoC: invalid widget private data size\n"); return -EINVAL; } -- 2.52.0