Skip to content

Commit

Permalink
Merge series "ASoC: Sanity checks and soc-topology updates" from Ceza…
Browse files Browse the repository at this point in the history
…ry Rojewski <[email protected]>:

Couple of soc-topology related changes and a use-after-free fix. Said fix
and two sanity checks for soc-topology lead the way. While the
use-after-free is quite obvious, the sanity checks are here to cover for
cases where user malformed the topology file -or- access to filesystem
somehow got interrupted during copy operation. We shouldn't be reading
outside the file boundary.

Afterward a change to soc_tplg_add_kcontrol(): device being passed to
soc_tplg_add_dcontrol() from comp->dev to tplg->dev which corrects
dev_xxx() invoked later on.
Also, device used for topology memory allocations from component->dev to
component->card->dev so memory gets freed each time card device (usually
platform device) is removed rather than the component device what may
happen less frequently.

Dummy component gets smarter and no longer overrides hw_params if
there are other components accociated with related struct
snd_soc_pcm_runtime instance.

Amadeusz Sławiński (5):
  ASoC: core: Remove invalid snd_soc_component_set_jack call
  ASoC: topology: Check for dapm widget completeness
  ASoC: topology: Use correct device for prints
  ASoC: topology: Change topology device to card device
  ASoC: Stop dummy from overriding hwparams

Cezary Rojewski (1):
  ASoC: topology: Add header payload_size verification

 sound/soc/soc-core.c     |  3 ---
 sound/soc/soc-topology.c | 34 ++++++++++++++++++++++++++++++----
 sound/soc/soc-utils.c    | 13 +++++++++++++
 3 files changed, 43 insertions(+), 7 deletions(-)

--
2.25.1
  • Loading branch information
broonie committed Oct 29, 2021
2 parents 1736323 + 6c50466 commit 956ac4f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 7 deletions.
3 changes: 0 additions & 3 deletions sound/soc/soc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1342,9 +1342,6 @@ static void soc_remove_component(struct snd_soc_component *component,
if (probed)
snd_soc_component_remove(component);

/* For framework level robustness */
snd_soc_component_set_jack(component, NULL, NULL);

list_del_init(&component->card_list);
snd_soc_dapm_free(snd_soc_component_get_dapm(component));
soc_cleanup_component_debugfs(component);
Expand Down
34 changes: 30 additions & 4 deletions sound/soc/soc-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ static int soc_tplg_add_kcontrol(struct soc_tplg *tplg,
struct snd_soc_component *comp = tplg->comp;

return soc_tplg_add_dcontrol(comp->card->snd_card,
comp->dev, k, comp->name_prefix, comp, kcontrol);
tplg->dev, k, comp->name_prefix, comp, kcontrol);
}

/* remove a mixer kcontrol */
Expand Down Expand Up @@ -1591,11 +1591,28 @@ static int soc_tplg_dapm_widget_elems_load(struct soc_tplg *tplg,
struct snd_soc_tplg_dapm_widget *widget = (struct snd_soc_tplg_dapm_widget *) tplg->pos;
int ret;

/*
* check if widget itself fits within topology file
* use sizeof instead of widget->size, as we can't be sure
* it is set properly yet (file may end before it is present)
*/
if (soc_tplg_get_offset(tplg) + sizeof(*widget) >= tplg->fw->size) {
dev_err(tplg->dev, "ASoC: invalid widget data size\n");
return -EINVAL;
}

/* check if widget has proper size */
if (le32_to_cpu(widget->size) != sizeof(*widget)) {
dev_err(tplg->dev, "ASoC: invalid widget size\n");
return -EINVAL;
}

/* check if widget private data fits within topology file */
if (soc_tplg_get_offset(tplg) + le32_to_cpu(widget->priv.size) >= tplg->fw->size) {
dev_err(tplg->dev, "ASoC: invalid widget private data size\n");
return -EINVAL;
}

ret = soc_tplg_dapm_widget_create(tplg, widget);
if (ret < 0) {
dev_err(tplg->dev, "ASoC: failed to load widget %s\n",
Expand Down Expand Up @@ -2438,6 +2455,7 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg,
_manifest = manifest;
} else {
abi_match = false;

ret = manifest_new_ver(tplg, manifest, &_manifest);
if (ret < 0)
return ret;
Expand Down Expand Up @@ -2468,6 +2486,14 @@ static int soc_valid_header(struct soc_tplg *tplg,
return -EINVAL;
}

if (soc_tplg_get_hdr_offset(tplg) + hdr->payload_size >= tplg->fw->size) {
dev_err(tplg->dev,
"ASoC: invalid header of type %d at offset %ld payload_size %d\n",
le32_to_cpu(hdr->type), soc_tplg_get_hdr_offset(tplg),
hdr->payload_size);
return -EINVAL;
}

/* big endian firmware objects not supported atm */
if (le32_to_cpu(hdr->magic) == SOC_TPLG_MAGIC_BIG_ENDIAN) {
dev_err(tplg->dev,
Expand Down Expand Up @@ -2642,17 +2668,17 @@ int snd_soc_tplg_component_load(struct snd_soc_component *comp,
/*
* check if we have sane parameters:
* comp - needs to exist to keep and reference data while parsing
* comp->dev - used for resource management and prints
* comp->card - used for setting card related parameters
* comp->card->dev - used for resource management and prints
* fw - we need it, as it is the very thing we parse
*/
if (!comp || !comp->dev || !comp->card || !fw)
if (!comp || !comp->card || !comp->card->dev || !fw)
return -EINVAL;

/* setup parsing context */
memset(&tplg, 0, sizeof(tplg));
tplg.fw = fw;
tplg.dev = comp->dev;
tplg.dev = comp->card->dev;
tplg.comp = comp;
if (ops) {
tplg.ops = ops;
Expand Down
13 changes: 13 additions & 0 deletions sound/soc/soc-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,23 @@ static const struct snd_pcm_hardware dummy_dma_hardware = {
.periods_max = 128,
};


static const struct snd_soc_component_driver dummy_platform;

static int dummy_dma_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
int i;

/*
* If there are other components associated with rtd, we shouldn't
* override their hwparams
*/
for_each_rtd_components(rtd, i, component) {
if (component->driver == &dummy_platform)
return 0;
}

/* BE's dont need dummy params */
if (!rtd->dai_link->no_pcm)
Expand Down

0 comments on commit 956ac4f

Please sign in to comment.