lkml.org 
[lkml]   [2018]   [Mar]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.18 20/25] staging: android: ashmem: Fix lockdep issue during llseek
    Date
    3.18-stable review patch.  If anyone has any objections, please let me know.

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

    From: Joel Fernandes <joelaf@google.com>

    commit cb57469c9573f6018cd1302953dd45d6e05aba7b upstream.

    ashmem_mutex create a chain of dependencies like so:

    (1)
    mmap syscall ->
    mmap_sem -> (acquired)
    ashmem_mmap
    ashmem_mutex (try to acquire)
    (block)

    (2)
    llseek syscall ->
    ashmem_llseek ->
    ashmem_mutex -> (acquired)
    inode_lock ->
    inode->i_rwsem (try to acquire)
    (block)

    (3)
    getdents ->
    iterate_dir ->
    inode_lock ->
    inode->i_rwsem (acquired)
    copy_to_user ->
    mmap_sem (try to acquire)

    There is a lock ordering created between mmap_sem and inode->i_rwsem
    causing a lockdep splat [2] during a syzcaller test, this patch fixes
    the issue by unlocking the mutex earlier. Functionally that's Ok since
    we don't need to protect vfs_llseek.

    [1] https://patchwork.kernel.org/patch/10185031/
    [2] https://lkml.org/lkml/2018/1/10/48

    Acked-by: Todd Kjos <tkjos@google.com>
    Cc: Arve Hjonnevag <arve@android.com>
    Cc: stable@vger.kernel.org
    Reported-by: syzbot+8ec30bb7bf1a981a2012@syzkaller.appspotmail.com
    Signed-off-by: Joel Fernandes <joelaf@google.com>
    Acked-by: Greg Hackmann <ghackmann@google.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/staging/android/ashmem.c | 15 +++++++--------
    1 file changed, 7 insertions(+), 8 deletions(-)

    --- a/drivers/staging/android/ashmem.c
    +++ b/drivers/staging/android/ashmem.c
    @@ -330,24 +330,23 @@ static loff_t ashmem_llseek(struct file
    mutex_lock(&ashmem_mutex);

    if (asma->size == 0) {
    - ret = -EINVAL;
    - goto out;
    + mutex_unlock(&ashmem_mutex);
    + return -EINVAL;
    }

    if (!asma->file) {
    - ret = -EBADF;
    - goto out;
    + mutex_unlock(&ashmem_mutex);
    + return -EBADF;
    }

    + mutex_unlock(&ashmem_mutex);
    +
    ret = vfs_llseek(asma->file, offset, origin);
    if (ret < 0)
    - goto out;
    + return ret;

    /** Copy f_pos from backing file, since f_ops->llseek() sets it */
    file->f_pos = asma->file->f_pos;
    -
    -out:
    - mutex_unlock(&ashmem_mutex);
    return ret;
    }


    \
     
     \ /
      Last update: 2018-03-16 16:26    [W:2.792 / U:0.264 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site