]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
ASoC: SOF: topology: Fix bytes control size checks
authorDragos Tarcatu <dragos_tarcatu@mentor.com>
Wed, 6 Nov 2019 14:58:16 +0000 (08:58 -0600)
committerMarcelo Henrique Cerri <marcelo.cerri@canonical.com>
Fri, 17 Jan 2020 17:22:53 +0000 (14:22 -0300)
BugLink: https://bugs.launchpad.net/bugs/1855306
[ Upstream commit 9508ef5a980f5d847cad9b932b6ada8f2a3466c1 ]

When using the example SOF amp widget topology, KASAN dumps this
when the AMP bytes kcontrol gets loaded:

[ 9.579548] BUG: KASAN: slab-out-of-bounds in
sof_control_load+0x8cc/0xac0 [snd_sof]
[ 9.588194] Write of size 40 at addr ffff8882314559dc by task
systemd-udevd/2411

Fix that by rejecting the topology if the bytes data size > max_size

Fixes: 311ce4fe7637d ("ASoC: SOF: Add support for loading topologies")
Reviewed-by: Jaska Uimonen <jaska.uimonen@intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Dragos Tarcatu <dragos_tarcatu@mentor.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20191106145816.9367-1-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Connor Kuehl <connor.kuehl@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
sound/soc/sof/topology.c

index 96230329e678f6a50e4bebc6b6ab8e3513d3565e..355f04663f57616aa9354ad7f09fe95fcfe9534f 100644 (file)
@@ -533,15 +533,16 @@ static int sof_control_load_bytes(struct snd_soc_component *scomp,
        struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value;
        int max_size = sbe->max;
 
-       if (le32_to_cpu(control->priv.size) > max_size) {
+       /* init the get/put bytes data */
+       scontrol->size = sizeof(struct sof_ipc_ctrl_data) +
+               le32_to_cpu(control->priv.size);
+
+       if (scontrol->size > max_size) {
                dev_err(sdev->dev, "err: bytes data size %d exceeds max %d.\n",
-                       control->priv.size, max_size);
+                       scontrol->size, max_size);
                return -EINVAL;
        }
 
-       /* init the get/put bytes data */
-       scontrol->size = sizeof(struct sof_ipc_ctrl_data) +
-               le32_to_cpu(control->priv.size);
        scontrol->control_data = kzalloc(max_size, GFP_KERNEL);
        cdata = scontrol->control_data;
        if (!scontrol->control_data)