Skip to content

Commit d850931

Browse files
tiwaigregkh
authored andcommitted
ALSA: aloop: Fix access to not-yet-ready substream via cable
commit 8e6b1a72a75bb5067ccb6b56d8ca4aa3a300a64e upstream. In loopback_open() and loopback_close(), we assign and release the substream object to the corresponding cable in a racy way. It's neither locked nor done in the right position. The open callback assigns the substream before its preparation finishes, hence the other side of the cable may pick it up, which may lead to the invalid memory access. This patch addresses these: move the assignment to the end of the open callback, and wrap with cable->lock for avoiding concurrent accesses. Cc: <[email protected]> Signed-off-by: Takashi Iwai <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e88d13e commit d850931

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

sound/drivers/aloop.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,9 @@ static void free_cable(struct snd_pcm_substream *substream)
667667
return;
668668
if (cable->streams[!substream->stream]) {
669669
/* other stream is still alive */
670+
spin_lock_irq(&cable->lock);
670671
cable->streams[substream->stream] = NULL;
672+
spin_unlock_irq(&cable->lock);
671673
} else {
672674
/* free the cable */
673675
loopback->cables[substream->number][dev] = NULL;
@@ -707,7 +709,6 @@ static int loopback_open(struct snd_pcm_substream *substream)
707709
loopback->cables[substream->number][dev] = cable;
708710
}
709711
dpcm->cable = cable;
710-
cable->streams[substream->stream] = dpcm;
711712

712713
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
713714

@@ -739,6 +740,11 @@ static int loopback_open(struct snd_pcm_substream *substream)
739740
runtime->hw = loopback_pcm_hardware;
740741
else
741742
runtime->hw = cable->hw;
743+
744+
spin_lock_irq(&cable->lock);
745+
cable->streams[substream->stream] = dpcm;
746+
spin_unlock_irq(&cable->lock);
747+
742748
unlock:
743749
if (err < 0) {
744750
free_cable(substream);

0 commit comments

Comments
 (0)