lkml.org 
[lkml]   [2021]   [Oct]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.14 004/151] ALSA: seq: Fix a potential UAF by wrong private_free call order
    Date
    From: Takashi Iwai <tiwai@suse.de>

    commit 1f8763c59c4ec6254d629fe77c0a52220bd907aa upstream.

    John Keeping reported and posted a patch for a potential UAF in
    rawmidi sequencer destruction: the snd_rawmidi_dev_seq_free() may be
    called after the associated rawmidi object got already freed.
    After a deeper look, it turned out that the bug is rather the
    incorrect private_free call order for a snd_seq_device. The
    snd_seq_device private_free gets called at the release callback of the
    sequencer device object, while this was rather expected to be executed
    at the snd_device call chains that runs at the beginning of the whole
    card-free procedure. It's been broken since the rewrite of
    sequencer-device binding (although it hasn't surfaced because the
    sequencer device release happens usually right along with the card
    device release).

    This patch corrects the private_free call to be done in the right
    place, at snd_seq_device_dev_free().

    Fixes: 7c37ae5c625a ("ALSA: seq: Rewrite sequencer device binding with standard bus")
    Reported-and-tested-by: John Keeping <john@metanate.com>
    Cc: <stable@vger.kernel.org>
    Link: https://lore.kernel.org/r/20210930114114.8645-1-tiwai@suse.de
    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    sound/core/seq_device.c | 8 +++-----
    1 file changed, 3 insertions(+), 5 deletions(-)

    --- a/sound/core/seq_device.c
    +++ b/sound/core/seq_device.c
    @@ -156,6 +156,8 @@ static int snd_seq_device_dev_free(struc
    struct snd_seq_device *dev = device->device_data;

    cancel_autoload_drivers();
    + if (dev->private_free)
    + dev->private_free(dev);
    put_device(&dev->dev);
    return 0;
    }
    @@ -183,11 +185,7 @@ static int snd_seq_device_dev_disconnect

    static void snd_seq_dev_release(struct device *dev)
    {
    - struct snd_seq_device *sdev = to_seq_dev(dev);
    -
    - if (sdev->private_free)
    - sdev->private_free(sdev);
    - kfree(sdev);
    + kfree(to_seq_dev(dev));
    }

    /*

    \
     
     \ /
      Last update: 2021-10-18 15:52    [W:3.387 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site