Commit abc3caac authored by Amadeusz Sławiński's avatar Amadeusz Sławiński Committed by Mark Brown

ASoC: topology: Add missing memory checks

kstrdup is an allocation function and it can fail, so its return value
should be checked and handled appropriately.

In order to check all cases, we need to modify set_stream_info to return
a value, so check that everything went correctly when doing kstrdup().
Later add proper checks and error handlers.
Signed-off-by: default avatarAmadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20200327204729.397-2-amadeuszx.slawinski@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent ccfc5316
......@@ -1766,10 +1766,13 @@ static int soc_tplg_dapm_complete(struct soc_tplg *tplg)
return 0;
}
static void set_stream_info(struct snd_soc_pcm_stream *stream,
static int set_stream_info(struct snd_soc_pcm_stream *stream,
struct snd_soc_tplg_stream_caps *caps)
{
stream->stream_name = kstrdup(caps->name, GFP_KERNEL);
if (!stream->stream_name)
return -ENOMEM;
stream->channels_min = le32_to_cpu(caps->channels_min);
stream->channels_max = le32_to_cpu(caps->channels_max);
stream->rates = le32_to_cpu(caps->rates);
......@@ -1777,6 +1780,8 @@ static void set_stream_info(struct snd_soc_pcm_stream *stream,
stream->rate_max = le32_to_cpu(caps->rate_max);
stream->formats = le64_to_cpu(caps->formats);
stream->sig_bits = le32_to_cpu(caps->sig_bits);
return 0;
}
static void set_dai_flags(struct snd_soc_dai_driver *dai_drv,
......@@ -1812,20 +1817,29 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
if (dai_drv == NULL)
return -ENOMEM;
if (strlen(pcm->dai_name))
if (strlen(pcm->dai_name)) {
dai_drv->name = kstrdup(pcm->dai_name, GFP_KERNEL);
if (!dai_drv->name) {
ret = -ENOMEM;
goto err;
}
}
dai_drv->id = le32_to_cpu(pcm->dai_id);
if (pcm->playback) {
stream = &dai_drv->playback;
caps = &pcm->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
set_stream_info(stream, caps);
ret = set_stream_info(stream, caps);
if (ret < 0)
goto err;
}
if (pcm->capture) {
stream = &dai_drv->capture;
caps = &pcm->caps[SND_SOC_TPLG_STREAM_CAPTURE];
set_stream_info(stream, caps);
ret = set_stream_info(stream, caps);
if (ret < 0)
goto err;
}
if (pcm->compress)
......@@ -1835,11 +1849,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
ret = soc_tplg_dai_load(tplg, dai_drv, pcm, NULL);
if (ret < 0) {
dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n");
kfree(dai_drv->playback.stream_name);
kfree(dai_drv->capture.stream_name);
kfree(dai_drv->name);
kfree(dai_drv);
return ret;
goto err;
}
dai_drv->dobj.index = tplg->index;
......@@ -1860,6 +1870,14 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
return ret;
}
return 0;
err:
kfree(dai_drv->playback.stream_name);
kfree(dai_drv->capture.stream_name);
kfree(dai_drv->name);
kfree(dai_drv);
return ret;
}
......@@ -1916,11 +1934,20 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg,
if (strlen(pcm->pcm_name)) {
link->name = kstrdup(pcm->pcm_name, GFP_KERNEL);
link->stream_name = kstrdup(pcm->pcm_name, GFP_KERNEL);
if (!link->name || !link->stream_name) {
ret = -ENOMEM;
goto err;
}
}
link->id = le32_to_cpu(pcm->pcm_id);
if (strlen(pcm->dai_name))
if (strlen(pcm->dai_name)) {
link->cpus->dai_name = kstrdup(pcm->dai_name, GFP_KERNEL);
if (!link->cpus->dai_name) {
ret = -ENOMEM;
goto err;
}
}
link->codecs->name = "snd-soc-dummy";
link->codecs->dai_name = "snd-soc-dummy-dai";
......@@ -2436,13 +2463,17 @@ static int soc_tplg_dai_config(struct soc_tplg *tplg,
if (d->playback) {
stream = &dai_drv->playback;
caps = &d->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
set_stream_info(stream, caps);
ret = set_stream_info(stream, caps);
if (ret < 0)
goto err;
}
if (d->capture) {
stream = &dai_drv->capture;
caps = &d->caps[SND_SOC_TPLG_STREAM_CAPTURE];
set_stream_info(stream, caps);
ret = set_stream_info(stream, caps);
if (ret < 0)
goto err;
}
if (d->flag_mask)
......@@ -2454,10 +2485,15 @@ static int soc_tplg_dai_config(struct soc_tplg *tplg,
ret = soc_tplg_dai_load(tplg, dai_drv, NULL, dai);
if (ret < 0) {
dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n");
return ret;
goto err;
}
return 0;
err:
kfree(dai_drv->playback.stream_name);
kfree(dai_drv->capture.stream_name);
return ret;
}
/* load physical DAI elements */
......
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