Re: [alsa-devel] [PATCH] ASoC: soc-core: Fix null pointer dereference in soc_find_component

From: Pierre-Louis Bossart
Date: Fri Jan 18 2019 - 18:02:14 EST



On 1/15/19 3:16 PM, Pierre-Louis Bossart wrote:

Beyond the fact that the platform_name seems to be totally useless,
additional tests show that the patch ('ASoC: soc-core: defer card probe
until all component is added to list') adds a new restriction which
contradicts existing error checks.

None of the Intel machine drivers set the dailink "cpu_name" field but use
the "cpu_dai_name" field instead. This was perfectly legit as documented by
the code at the end of soc_init_dai_link()
This should be fixed by the patch
"ASoC: core: Don't defer probe on optional, NULL components" which Mark
already applied to his tree. See
http://mailman.alsa-project.org/pipermail/alsa-devel/2019-January/144323.html

Ah yes, I missed this patch while I was debugging. Indeed this fixes the problem and my devices work again with Mark's for-next branch. Thanks Matthias!

This PROBE_DEFER support actually breaks the topology override that we've been relying on for SOF (and which has been in Mark's branch for some time now). This override helps us reuse machine drivers between legacy and SOF-based solutions.

With the current code, the tests in soc_register_card() complain that the platform_name can't be tied to a component and stop the card registration, but that's mainly because the tests are done before the topology overrides are done in soc_check_tplg_fes(). Moving soc_check_tplg_fes() from soc_instantiate_card() to an earlier time in soc_register_card() works-around the problem but looks quite invasive (mutex lock, etc).

There is also a second problem where we seem to have a memory management issue root caused to the change in snd_soc_init_platform() added by 09ac6a817bd6 ('ASoC: soc-core: fix init platform memory handling')

The code does this

static int snd_soc_init_platform(struct snd_soc_card *card,
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ Âstruct snd_soc_dai_link *dai_link)
{
ÂÂÂ struct snd_soc_dai_link_component *platform = dai_link->platform;


ÂÂÂ /* convert Legacy platform link */
ÂÂÂ if (!platform || dai_link->legacy_platform) {
ÂÂÂ ÂÂÂ platform = devm_kzalloc(card->dev,
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ sizeof(struct snd_soc_dai_link_component),
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ GFP_KERNEL);
ÂÂÂ ÂÂÂ if (!platform)
ÂÂÂ ÂÂÂ ÂÂÂ return -ENOMEM;

ÂÂÂ ÂÂÂ dai_link->platformÂÂÂ Â = platform;
ÂÂÂ ÂÂÂ dai_link->legacy_platform = 1;

This last assignment guarantees that memory will be allocated every time this function is called, and whatever overrides are done later will themselves be overridden by the new allocation. I am not sure what the intent was here, Curtis can you please double-check?

Details, test code and logs are available here: https://github.com/thesofproject/linux/issues/565

Have a nice week-end everyone, that's it for me until Tuesday.

-Pierre