lkml.org 
[lkml]   [2018]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 388/410] ALSA: aloop: Fix access to not-yet-ready substream via cable
    3.16.57-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Takashi Iwai <tiwai@suse.de>

    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.

    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    sound/drivers/aloop.c | 8 +++++++-
    1 file changed, 7 insertions(+), 1 deletion(-)

    --- a/sound/drivers/aloop.c
    +++ b/sound/drivers/aloop.c
    @@ -667,7 +667,9 @@ static void free_cable(struct snd_pcm_su
    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;
    @@ -707,7 +709,6 @@ static int loopback_open(struct snd_pcm_
    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);

    @@ -739,6 +740,11 @@ static int loopback_open(struct snd_pcm_
    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);
    \
     
     \ /
      Last update: 2018-06-07 16:15    [W:6.858 / U:0.532 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site