Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc0e7345 authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Vinod Koul
Browse files

ALSA: pcm_dmaengine: Properly synchronize DMA on shutdown



Use the new dmaengine_synchronize() function to make sure that all complete
callbacks have finished running before the runtime data, which is accessed
in the completed callback, is freed.

This fixes a long standing use-after-free race condition that has been
observed on some systems.

Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Reviewed-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
parent 860dd64c
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -202,13 +202,13 @@ int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
		if (runtime->info & SNDRV_PCM_INFO_PAUSE)
			dmaengine_pause(prtd->dma_chan);
		else
			dmaengine_terminate_all(prtd->dma_chan);
			dmaengine_terminate_async(prtd->dma_chan);
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		dmaengine_pause(prtd->dma_chan);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		dmaengine_terminate_all(prtd->dma_chan);
		dmaengine_terminate_async(prtd->dma_chan);
		break;
	default:
		return -EINVAL;
@@ -346,6 +346,7 @@ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream)
{
	struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);

	dmaengine_synchronize(prtd->dma_chan);
	kfree(prtd);

	return 0;
@@ -362,9 +363,11 @@ int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream)
{
	struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);

	dmaengine_synchronize(prtd->dma_chan);
	dma_release_channel(prtd->dma_chan);
	kfree(prtd);

	return snd_dmaengine_pcm_close(substream);
	return 0;
}
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close_release_chan);