[alsa-devel] [PATCH 2/2] ASoC: topology: don't access beyond topology data

Guennadi Liakhovetski guennadi.liakhovetski at linux.intel.com
Mon Oct 7 10:41:33 CEST 2019


When loading kcontrol elements make sure to first check the size of
available data before accessing it.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski at linux.intel.com>
---
 sound/soc/soc-topology.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
index d1d3c6f..f933ad4 100644
--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -1115,11 +1115,11 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg,
 	struct snd_soc_tplg_hdr *hdr)
 {
 	struct snd_soc_tplg_ctl_hdr *control_hdr;
+	ssize_t remainder = le32_to_cpu(hdr->payload_size);
 	int i;
 
 	if (tplg->pass != SOC_TPLG_PASS_MIXER) {
-		tplg->pos += le32_to_cpu(hdr->size) +
-			le32_to_cpu(hdr->payload_size);
+		tplg->pos += le32_to_cpu(hdr->size) + remainder;
 		return 0;
 	}
 
@@ -1130,6 +1130,11 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg,
 
 		control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos;
 
+		if (remainder < sizeof(*control_hdr)) {
+			dev_err(tplg->dev, "ASoC: invalid payload size\n");
+			return -EINVAL;
+		}
+
 		if (le32_to_cpu(control_hdr->size) != sizeof(*control_hdr)) {
 			dev_err(tplg->dev, "ASoC: invalid control size\n");
 			return -EINVAL;
@@ -1143,25 +1148,24 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg,
 		case SND_SOC_TPLG_CTL_RANGE:
 		case SND_SOC_TPLG_DAPM_CTL_VOLSW:
 		case SND_SOC_TPLG_DAPM_CTL_PIN:
-			soc_tplg_dmixer_create(tplg, 1,
-					       le32_to_cpu(hdr->payload_size));
+			soc_tplg_dmixer_create(tplg, 1, remainder);
 			break;
 		case SND_SOC_TPLG_CTL_ENUM:
 		case SND_SOC_TPLG_CTL_ENUM_VALUE:
 		case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
 		case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
 		case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
-			soc_tplg_denum_create(tplg, 1,
-					      le32_to_cpu(hdr->payload_size));
+			soc_tplg_denum_create(tplg, 1, remainder);
 			break;
 		case SND_SOC_TPLG_CTL_BYTES:
-			soc_tplg_dbytes_create(tplg, 1,
-					       le32_to_cpu(hdr->payload_size));
+			soc_tplg_dbytes_create(tplg, 1, remainder);
 			break;
 		default:
 			soc_bind_err(tplg, control_hdr, i);
 			return -EINVAL;
 		}
+
+		remainder -= tplg->pos - (u8 *)control_hdr;
 	}
 
 	return 0;
-- 
1.9.3



More information about the Alsa-devel mailing list