lkml.org 
[lkml]   [2021]   [Nov]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 050/917] ALSA: timer: Fix use-after-free problem
    Date
    From: Wang Wensheng <wangwensheng4@huawei.com>

    commit c0317c0e87094f5b5782b6fdef5ae0a4b150496c upstream.

    When the timer instance was add into ack_list but was not currently in
    process, the user could stop it via snd_timer_stop1() without delete it
    from the ack_list. Then the user could free the timer instance and when
    it was actually processed UAF occurred.

    This issue could be reproduced via testcase snd_timer01 in ltp - running
    several instances of that testcase at the same time.

    What I actually met was that the ack_list of the timer broken and the
    kernel went into deadloop with irqoff. That could be detected by
    hardlockup detector on board or when we run it on qemu, we could use gdb
    to dump the ack_list when the console has no response.

    To fix this issue, we delete the timer instance from ack_list and
    active_list unconditionally in snd_timer_stop1().

    Signed-off-by: Wang Wensheng <wangwensheng4@huawei.com>
    Suggested-by: Takashi Iwai <tiwai@suse.de>
    Cc: <stable@vger.kernel.org>
    Link: https://lore.kernel.org/r/20211103033517.80531-1-wangwensheng4@huawei.com
    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    sound/core/timer.c | 4 ++--
    1 file changed, 2 insertions(+), 2 deletions(-)

    --- a/sound/core/timer.c
    +++ b/sound/core/timer.c
    @@ -624,13 +624,13 @@ static int snd_timer_stop1(struct snd_ti
    if (!timer)
    return -EINVAL;
    spin_lock_irqsave(&timer->lock, flags);
    + list_del_init(&timeri->ack_list);
    + list_del_init(&timeri->active_list);
    if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
    SNDRV_TIMER_IFLG_START))) {
    result = -EBUSY;
    goto unlock;
    }
    - list_del_init(&timeri->ack_list);
    - list_del_init(&timeri->active_list);
    if (timer->card && timer->card->shutdown)
    goto unlock;
    if (stop) {

    \
     
     \ /
      Last update: 2021-11-16 00:29    [W:2.892 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site