Skip to content

Commit dd9f9cc

Browse files
Amadeusz Sławińskibroonie
authored andcommitted
ASoC: core: Do not call link_exit() on uninitialized rtd objects
On init we have sequence: for_each_card_prelinks(card, i, dai_link) { ret = snd_soc_add_pcm_runtime(card, dai_link); ret = init_some_other_things(...); if (ret) goto probe_end: for_each_card_rtds(card, rtd) { ret = soc_init_pcm_runtime(card, rtd); probe_end: while on exit: for_each_card_rtds(card, rtd) snd_soc_link_exit(rtd); If init_some_other_things() step fails due to error we end up with not fully setup rtds and try to call snd_soc_link_exit on them, which depending on contents on .link_exit handler, can end up dereferencing NULL pointer. Reviewed-by: Cezary Rojewski <[email protected]> Signed-off-by: Amadeusz Sławiński <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent e80f238 commit dd9f9cc

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

include/sound/soc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,8 @@ struct snd_soc_pcm_runtime {
11261126
unsigned int pop_wait:1;
11271127
unsigned int fe_compr:1; /* for Dynamic PCM */
11281128

1129+
bool initialized;
1130+
11291131
int num_components;
11301132
struct snd_soc_component *components[]; /* CPU/Codec/Platform */
11311133
};

sound/soc/soc-core.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,7 +1347,7 @@ static int soc_init_pcm_runtime(struct snd_soc_card *card,
13471347
snd_soc_runtime_get_dai_fmt(rtd);
13481348
ret = snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt);
13491349
if (ret)
1350-
return ret;
1350+
goto err;
13511351

13521352
/* add DPCM sysfs entries */
13531353
soc_dpcm_debugfs_add(rtd);
@@ -1372,17 +1372,26 @@ static int soc_init_pcm_runtime(struct snd_soc_card *card,
13721372
/* create compress_device if possible */
13731373
ret = snd_soc_dai_compress_new(cpu_dai, rtd, num);
13741374
if (ret != -ENOTSUPP)
1375-
return ret;
1375+
goto err;
13761376

13771377
/* create the pcm */
13781378
ret = soc_new_pcm(rtd, num);
13791379
if (ret < 0) {
13801380
dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
13811381
dai_link->stream_name, ret);
1382-
return ret;
1382+
goto err;
13831383
}
13841384

1385-
return snd_soc_pcm_dai_new(rtd);
1385+
ret = snd_soc_pcm_dai_new(rtd);
1386+
if (ret < 0)
1387+
goto err;
1388+
1389+
rtd->initialized = true;
1390+
1391+
return 0;
1392+
err:
1393+
snd_soc_link_exit(rtd);
1394+
return ret;
13861395
}
13871396

13881397
static void soc_set_name_prefix(struct snd_soc_card *card,
@@ -1980,7 +1989,8 @@ static void soc_cleanup_card_resources(struct snd_soc_card *card)
19801989

19811990
/* release machine specific resources */
19821991
for_each_card_rtds(card, rtd)
1983-
snd_soc_link_exit(rtd);
1992+
if (rtd->initialized)
1993+
snd_soc_link_exit(rtd);
19841994
/* remove and free each DAI */
19851995
soc_remove_link_dais(card);
19861996
soc_remove_link_components(card);

0 commit comments

Comments
 (0)