Skip to content

Commit

Permalink
ALSA: aloop: Fix access to not-yet-ready substream via cable
Browse files Browse the repository at this point in the history
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: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Mar 22, 2018
1 parent 67a01af commit 8e6b1a7
Showing 1 changed file with 7 additions and 1 deletion.
8 changes: 7 additions & 1 deletion sound/drivers/aloop.c
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,9 @@ static void free_cable(struct snd_pcm_substream *substream)
return;
if (cable->streams[!substream->stream]) {
/* other stream is still alive */
spin_lock_irq(&cable->lock);
cable->streams[substream->stream] = NULL;
spin_unlock_irq(&cable->lock);
} else {
/* free the cable */
loopback->cables[substream->number][dev] = NULL;
Expand Down Expand Up @@ -705,7 +707,6 @@ static int loopback_open(struct snd_pcm_substream *substream)
loopback->cables[substream->number][dev] = cable;
}
dpcm->cable = cable;
cable->streams[substream->stream] = dpcm;

snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);

Expand Down Expand Up @@ -737,6 +738,11 @@ static int loopback_open(struct snd_pcm_substream *substream)
runtime->hw = loopback_pcm_hardware;
else
runtime->hw = cable->hw;

spin_lock_irq(&cable->lock);
cable->streams[substream->stream] = dpcm;
spin_unlock_irq(&cable->lock);

unlock:
if (err < 0) {
free_cable(substream);
Expand Down

0 comments on commit 8e6b1a7

Please sign in to comment.