diff options
author | Dragos Tarcatu <dragos_tarcatu@mentor.com> | 2019-11-06 09:58:16 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2019-11-06 10:31:12 -0500 |
commit | 9508ef5a980f5d847cad9b932b6ada8f2a3466c1 (patch) | |
tree | c2c6e0ebd24d1fb6904217eced068176ba19019c | |
parent | e44f3d49f900c645af434a3a1dfdbfb79c4a7851 (diff) |
ASoC: SOF: topology: Fix bytes control size checks
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>
-rw-r--r-- | sound/soc/sof/topology.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 0aabb3190ddc..4452594c2e17 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c | |||
@@ -543,15 +543,16 @@ static int sof_control_load_bytes(struct snd_soc_component *scomp, | |||
543 | struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value; | 543 | struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value; |
544 | int max_size = sbe->max; | 544 | int max_size = sbe->max; |
545 | 545 | ||
546 | if (le32_to_cpu(control->priv.size) > max_size) { | 546 | /* init the get/put bytes data */ |
547 | scontrol->size = sizeof(struct sof_ipc_ctrl_data) + | ||
548 | le32_to_cpu(control->priv.size); | ||
549 | |||
550 | if (scontrol->size > max_size) { | ||
547 | dev_err(sdev->dev, "err: bytes data size %d exceeds max %d.\n", | 551 | dev_err(sdev->dev, "err: bytes data size %d exceeds max %d.\n", |
548 | control->priv.size, max_size); | 552 | scontrol->size, max_size); |
549 | return -EINVAL; | 553 | return -EINVAL; |
550 | } | 554 | } |
551 | 555 | ||
552 | /* init the get/put bytes data */ | ||
553 | scontrol->size = sizeof(struct sof_ipc_ctrl_data) + | ||
554 | le32_to_cpu(control->priv.size); | ||
555 | scontrol->control_data = kzalloc(max_size, GFP_KERNEL); | 556 | scontrol->control_data = kzalloc(max_size, GFP_KERNEL); |
556 | cdata = scontrol->control_data; | 557 | cdata = scontrol->control_data; |
557 | if (!scontrol->control_data) | 558 | if (!scontrol->control_data) |