Skip to content

Commit f4aa5e2

Browse files
charleskeepaxbroonie
authored andcommitted
ASoC: dapm: Move dai_link widgets to runtime to fix use after free
The newly added CODEC to CODEC DAI link widget pointers in snd_soc_dai_link are better placed in snd_soc_pcm_runtime. snd_soc_dai_link is really intended for static configuration of the DAI, and the runtime for dynamic data. The snd_soc_dai_link structures are not destroyed if the card is unbound. The widgets are cleared up on unbind, however if the card is rebound as the snd_soc_dai_link structures are reused these pointers will be left at their old values, causing access to freed memory. Fixes: 595571c ("ASoC: dapm: Fix regression introducing multiple copies of DAI widgets") Signed-off-by: Charles Keepax <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 53a58bf commit f4aa5e2

File tree

2 files changed

+9
-9
lines changed

2 files changed

+9
-9
lines changed

include/sound/soc.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -790,9 +790,6 @@ struct snd_soc_dai_link {
790790
const struct snd_soc_pcm_stream *params;
791791
unsigned int num_params;
792792

793-
struct snd_soc_dapm_widget *playback_widget;
794-
struct snd_soc_dapm_widget *capture_widget;
795-
796793
unsigned int dai_fmt; /* format to set on init */
797794

798795
enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */
@@ -1156,6 +1153,9 @@ struct snd_soc_pcm_runtime {
11561153
struct snd_soc_dai **cpu_dais;
11571154
unsigned int num_cpus;
11581155

1156+
struct snd_soc_dapm_widget *playback_widget;
1157+
struct snd_soc_dapm_widget *capture_widget;
1158+
11591159
struct delayed_work delayed_work;
11601160
void (*close_delayed_work_func)(struct snd_soc_pcm_runtime *rtd);
11611161
#ifdef CONFIG_DEBUG_FS

sound/soc/soc-dapm.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4340,16 +4340,16 @@ static void dapm_connect_dai_pair(struct snd_soc_card *card,
43404340
codec = codec_dai->playback_widget;
43414341

43424342
if (playback_cpu && codec) {
4343-
if (dai_link->params && !dai_link->playback_widget) {
4343+
if (dai_link->params && !rtd->playback_widget) {
43444344
substream = streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
43454345
dai = snd_soc_dapm_new_dai(card, substream, "playback");
43464346
if (IS_ERR(dai))
43474347
goto capture;
4348-
dai_link->playback_widget = dai;
4348+
rtd->playback_widget = dai;
43494349
}
43504350

43514351
dapm_connect_dai_routes(&card->dapm, cpu_dai, playback_cpu,
4352-
dai_link->playback_widget,
4352+
rtd->playback_widget,
43534353
codec_dai, codec);
43544354
}
43554355

@@ -4358,16 +4358,16 @@ static void dapm_connect_dai_pair(struct snd_soc_card *card,
43584358
codec = codec_dai->capture_widget;
43594359

43604360
if (codec && capture_cpu) {
4361-
if (dai_link->params && !dai_link->capture_widget) {
4361+
if (dai_link->params && !rtd->capture_widget) {
43624362
substream = streams[SNDRV_PCM_STREAM_CAPTURE].substream;
43634363
dai = snd_soc_dapm_new_dai(card, substream, "capture");
43644364
if (IS_ERR(dai))
43654365
return;
4366-
dai_link->capture_widget = dai;
4366+
rtd->capture_widget = dai;
43674367
}
43684368

43694369
dapm_connect_dai_routes(&card->dapm, codec_dai, codec,
4370-
dai_link->capture_widget,
4370+
rtd->capture_widget,
43714371
cpu_dai, capture_cpu);
43724372
}
43734373
}

0 commit comments

Comments
 (0)