lkml.org 
[lkml]   [2013]   [Jul]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 142/145] lockd: protect nlm_blocked access in nlmsvc_retry_blocked
    Date
    3.8.13.5 -stable review patch.  If anyone has any objections, please let me know.

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

    From: David Jeffery <djeffery@redhat.com>

    commit 1c327d962fc420aea046c16215a552710bde8231 upstream.

    In nlmsvc_retry_blocked, the check that the list is non-empty and acquiring
    the pointer of the first entry is unprotected by any lock. This allows a rare
    race condition when there is only one entry on the list. A function such as
    nlmsvc_grant_callback() can be called, which will temporarily remove the entry
    from the list. Between the list_empty() and list_entry(),the list may become
    empty, causing an invalid pointer to be used as an nlm_block, leading to a
    possible crash.

    This patch adds the nlm_block_lock around these calls to prevent concurrent
    use of the nlm_blocked list.

    This was a regression introduced by
    f904be9cc77f361d37d71468b13ff3d1a1823dea "lockd: Mostly remove BKL from
    the server".

    Cc: Bryan Schumaker <bjschuma@netapp.com>
    Signed-off-by: David Jeffery <djeffery@redhat.com>
    Signed-off-by: J. Bruce Fields <bfields@redhat.com>
    Signed-off-by: Kamal Mostafa <kamal@canonical.com>
    ---
    fs/lockd/svclock.c | 4 ++++
    1 file changed, 4 insertions(+)

    diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
    index 8d80c99..57a3922 100644
    --- a/fs/lockd/svclock.c
    +++ b/fs/lockd/svclock.c
    @@ -939,6 +939,7 @@ nlmsvc_retry_blocked(void)
    unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
    struct nlm_block *block;

    + spin_lock(&nlm_blocked_lock);
    while (!list_empty(&nlm_blocked) && !kthread_should_stop()) {
    block = list_entry(nlm_blocked.next, struct nlm_block, b_list);

    @@ -948,6 +949,7 @@ nlmsvc_retry_blocked(void)
    timeout = block->b_when - jiffies;
    break;
    }
    + spin_unlock(&nlm_blocked_lock);

    dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
    block, block->b_when);
    @@ -957,7 +959,9 @@ nlmsvc_retry_blocked(void)
    retry_deferred_block(block);
    } else
    nlmsvc_grant_blocked(block);
    + spin_lock(&nlm_blocked_lock);
    }
    + spin_unlock(&nlm_blocked_lock);

    return timeout;
    }
    --
    1.8.1.2


    \
     
     \ /
      Last update: 2013-07-18 02:01    [W:4.075 / U:0.060 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site