lkml.org 
[lkml]   [2022]   [Jun]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 152/167] md: protect md_unregister_thread from reentrancy
    Date
    From: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>

    [ Upstream commit 1e267742283a4b5a8ca65755c44166be27e9aa0f ]

    Generally, the md_unregister_thread is called with reconfig_mutex, but
    raid_message in dm-raid doesn't hold reconfig_mutex to unregister thread,
    so md_unregister_thread can be called simulitaneously from two call sites
    in theory.

    Then after previous commit which remove the protection of reconfig_mutex
    for md_unregister_thread completely, the potential issue could be worse
    than before.

    Let's take pers_lock at the beginning of function to ensure reentrancy.

    Reported-by: Donald Buczek <buczek@molgen.mpg.de>
    Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
    Signed-off-by: Song Liu <song@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/md/md.c | 15 ++++++++++-----
    1 file changed, 10 insertions(+), 5 deletions(-)

    diff --git a/drivers/md/md.c b/drivers/md/md.c
    index 0197d18b5407..9e8373e7e287 100644
    --- a/drivers/md/md.c
    +++ b/drivers/md/md.c
    @@ -7254,17 +7254,22 @@ EXPORT_SYMBOL(md_register_thread);

    void md_unregister_thread(struct md_thread **threadp)
    {
    - struct md_thread *thread = *threadp;
    - if (!thread)
    - return;
    - pr_debug("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
    - /* Locking ensures that mddev_unlock does not wake_up a
    + struct md_thread *thread;
    +
    + /*
    + * Locking ensures that mddev_unlock does not wake_up a
    * non-existent thread
    */
    spin_lock(&pers_lock);
    + thread = *threadp;
    + if (!thread) {
    + spin_unlock(&pers_lock);
    + return;
    + }
    *threadp = NULL;
    spin_unlock(&pers_lock);

    + pr_debug("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
    kthread_stop(thread->tsk);
    kfree(thread);
    }
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-06-13 12:32    [W:4.069 / U:1.324 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site