From dd0eff710d9076049a5427fa5e7a79e315065a7c Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 12 May 2026 08:32:02 +0300 Subject: [PATCH] ASoC: SOF: ipc3-control: Reject ABI data size larger than the TLV payload sof_ipc3_bytes_ext_put() copies header.length bytes from user space into cdata->data, but the amount of payload later sent to the firmware is taken from the ABI header's own size field. Nothing checks that the two agree, so a user claiming a size larger than the data it actually provided makes the driver send the stale tail of the previous control value to the DSP. The same stale tail is returned to user space by a subsequent bytes_ext_get() that does not read back from the DSP. Reject the payload if the ABI size field exceeds the data available in the TLV block. header.length has already been verified to be at least sizeof(struct sof_abi_hdr), so the subtraction cannot underflow. Fixes: 67ec2a091630 ("ASoC: SOF: Add bytes_ext control IPC ops for IPC3") Cc: stable@vger.kernel.org Signed-off-by: Peter Ujfalusi --- sound/soc/sof/ipc3-control.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sound/soc/sof/ipc3-control.c b/sound/soc/sof/ipc3-control.c index d1697401b1da0d..1b64145a3a3c0e 100644 --- a/sound/soc/sof/ipc3-control.c +++ b/sound/soc/sof/ipc3-control.c @@ -380,6 +380,7 @@ static int sof_ipc3_bytes_ext_put(struct snd_sof_control *scontrol, struct sof_ipc_ctrl_data *cdata = scontrol->ipc_control_data; struct snd_soc_component *scomp = scontrol->scomp; struct snd_ctl_tlv header; + unsigned int payload; int ret = -EINVAL; /* @@ -449,6 +450,15 @@ static int sof_ipc3_bytes_ext_put(struct snd_sof_control *scontrol, goto err_restore; } + /* header.length has been verified to be >= sizeof(struct sof_abi_hdr) */ + payload = header.length - sizeof(struct sof_abi_hdr); + if (cdata->data->size > payload) { + dev_err_ratelimited(scomp->dev, + "ABI header claims %u bytes of data, TLV carries %u\n", + cdata->data->size, payload); + goto err_restore; + } + /* notify DSP of byte control updates */ if (pm_runtime_active(scomp->dev)) { /* Actually send the data to the DSP; this is an opportunity to validate the data */