Commit 06eb49f7 authored by Mengdong Lin's avatar Mengdong Lin Committed by Mark Brown

ASoC: topology: Check size mismatch of ABI objects before parsing

If size mismatch of manifest, ABI headers or elements is found, stop
parsing topology info and return the error.

New fields may be append to the tail of ABI objects which will cause
object size to increase. If user space and kernel use different versions
of ABI, size mismatch will be detected here.
Signed-off-by: default avatarMengdong Lin <mengdong.lin@linux.intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 7de76b62
...@@ -1023,6 +1023,11 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg, ...@@ -1023,6 +1023,11 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg,
control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos; control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos;
if (control_hdr->size != sizeof(*control_hdr)) {
dev_err(tplg->dev, "ASoC: invalid control size\n");
return -EINVAL;
}
switch (control_hdr->ops.info) { switch (control_hdr->ops.info) {
case SND_SOC_TPLG_CTL_VOLSW: case SND_SOC_TPLG_CTL_VOLSW:
case SND_SOC_TPLG_CTL_STROBE: case SND_SOC_TPLG_CTL_STROBE:
...@@ -1499,6 +1504,11 @@ static int soc_tplg_dapm_widget_elems_load(struct soc_tplg *tplg, ...@@ -1499,6 +1504,11 @@ static int soc_tplg_dapm_widget_elems_load(struct soc_tplg *tplg,
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
widget = (struct snd_soc_tplg_dapm_widget *) tplg->pos; widget = (struct snd_soc_tplg_dapm_widget *) tplg->pos;
if (widget->size != sizeof(*widget)) {
dev_err(tplg->dev, "ASoC: invalid widget size\n");
return -EINVAL;
}
ret = soc_tplg_dapm_widget_create(tplg, widget); ret = soc_tplg_dapm_widget_create(tplg, widget);
if (ret < 0) { if (ret < 0) {
dev_err(tplg->dev, "ASoC: failed to load widget %s\n", dev_err(tplg->dev, "ASoC: failed to load widget %s\n",
...@@ -1652,8 +1662,6 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg, ...@@ -1652,8 +1662,6 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
if (tplg->pass != SOC_TPLG_PASS_PCM_DAI) if (tplg->pass != SOC_TPLG_PASS_PCM_DAI)
return 0; return 0;
pcm = (struct snd_soc_tplg_pcm *)tplg->pos;
if (soc_tplg_check_elem_count(tplg, if (soc_tplg_check_elem_count(tplg,
sizeof(struct snd_soc_tplg_pcm), count, sizeof(struct snd_soc_tplg_pcm), count,
hdr->payload_size, "PCM DAI")) { hdr->payload_size, "PCM DAI")) {
...@@ -1663,7 +1671,13 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg, ...@@ -1663,7 +1671,13 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
} }
/* create the FE DAIs and DAI links */ /* create the FE DAIs and DAI links */
pcm = (struct snd_soc_tplg_pcm *)tplg->pos;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if (pcm->size != sizeof(*pcm)) {
dev_err(tplg->dev, "ASoC: invalid pcm size\n");
return -EINVAL;
}
soc_tplg_pcm_create(tplg, pcm); soc_tplg_pcm_create(tplg, pcm);
pcm++; pcm++;
} }
...@@ -1683,6 +1697,11 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg, ...@@ -1683,6 +1697,11 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg,
return 0; return 0;
manifest = (struct snd_soc_tplg_manifest *)tplg->pos; manifest = (struct snd_soc_tplg_manifest *)tplg->pos;
if (manifest->size != sizeof(*manifest)) {
dev_err(tplg->dev, "ASoC: invalid manifest size\n");
return -EINVAL;
}
tplg->pos += sizeof(struct snd_soc_tplg_manifest); tplg->pos += sizeof(struct snd_soc_tplg_manifest);
if (tplg->comp && tplg->ops && tplg->ops->manifest) if (tplg->comp && tplg->ops && tplg->ops->manifest)
...@@ -1699,6 +1718,14 @@ static int soc_valid_header(struct soc_tplg *tplg, ...@@ -1699,6 +1718,14 @@ static int soc_valid_header(struct soc_tplg *tplg,
if (soc_tplg_get_hdr_offset(tplg) >= tplg->fw->size) if (soc_tplg_get_hdr_offset(tplg) >= tplg->fw->size)
return 0; return 0;
if (hdr->size != sizeof(*hdr)) {
dev_err(tplg->dev,
"ASoC: invalid header size for type %d at offset 0x%lx size 0x%zx.\n",
hdr->type, soc_tplg_get_hdr_offset(tplg),
tplg->fw->size);
return -EINVAL;
}
/* big endian firmware objects not supported atm */ /* big endian firmware objects not supported atm */
if (hdr->magic == cpu_to_be32(SND_SOC_TPLG_MAGIC)) { if (hdr->magic == cpu_to_be32(SND_SOC_TPLG_MAGIC)) {
dev_err(tplg->dev, dev_err(tplg->dev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment