lkml.org 
[lkml]   [2018]   [Feb]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.2 045/140] ALSA: rawmidi: Avoid racy info ioctl via ctl device
    3.2.100-rc1 review patch.  If anyone has any objections, please let me know.

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

    From: Takashi Iwai <tiwai@suse.de>

    commit c1cfd9025cc394fd137a01159d74335c5ac978ce upstream.

    The rawmidi also allows to obtaining the information via ioctl of ctl
    API. It means that user can issue an ioctl to the rawmidi device even
    when it's being removed as long as the control device is present.
    Although the code has some protection via the global register_mutex,
    its range is limited to the search of the corresponding rawmidi
    object, and the mutex is already unlocked at accessing the rawmidi
    object. This may lead to a use-after-free.

    For avoiding it, this patch widens the application of register_mutex
    to the whole snd_rawmidi_info_select() function. We have another
    mutex per rawmidi object, but this operation isn't very hot path, so
    it shouldn't matter from the performance POV.

    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    [bwh: Backported to 3.2: adjust context]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    sound/core/rawmidi.c | 15 ++++++++++++---
    1 file changed, 12 insertions(+), 3 deletions(-)

    --- a/sound/core/rawmidi.c
    +++ b/sound/core/rawmidi.c
    @@ -575,15 +575,14 @@ static int snd_rawmidi_info_user(struct
    return 0;
    }

    -int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info)
    +static int __snd_rawmidi_info_select(struct snd_card *card,
    + struct snd_rawmidi_info *info)
    {
    struct snd_rawmidi *rmidi;
    struct snd_rawmidi_str *pstr;
    struct snd_rawmidi_substream *substream;

    - mutex_lock(&register_mutex);
    rmidi = snd_rawmidi_search(card, info->device);
    - mutex_unlock(&register_mutex);
    if (!rmidi)
    return -ENXIO;
    if (info->stream < 0 || info->stream > 1)
    @@ -600,6 +599,16 @@ int snd_rawmidi_info_select(struct snd_c
    return -ENXIO;
    }

    +int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info)
    +{
    + int ret;
    +
    + mutex_lock(&register_mutex);
    + ret = __snd_rawmidi_info_select(card, info);
    + mutex_unlock(&register_mutex);
    + return ret;
    +}
    +
    static int snd_rawmidi_info_select_user(struct snd_card *card,
    struct snd_rawmidi_info __user *_info)
    {
    \
     
     \ /
      Last update: 2018-02-28 16:26    [W:3.901 / U:0.116 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site