lkml.org 
[lkml]   [2018]   [Sep]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 078/107] fuse: Fix oops at process_init_reply()
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

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

    From: Miklos Szeredi <mszeredi@redhat.com>

    commit e8f3bd773d22f488724dffb886a1618da85c2966 upstream.

    syzbot is hitting NULL pointer dereference at process_init_reply().
    This is because deactivate_locked_super() is called before response for
    initial request is processed.

    Fix this by aborting and waiting for all requests (including FUSE_INIT)
    before resetting fc->sb.

    Original patch by Tetsuo Handa <penguin-kernel@I-love.SKAURA.ne.jp>.

    Reported-by: syzbot <syzbot+b62f08f4d5857755e3bc@syzkaller.appspotmail.com>
    Fixes: e27c9d3877a0 ("fuse: fuse: add time_gran to INIT_OUT")
    Cc: <stable@vger.kernel.org> # v3.19
    Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/fuse/inode.c | 25 +++++++++++--------------
    1 file changed, 11 insertions(+), 14 deletions(-)

    --- a/fs/fuse/inode.c
    +++ b/fs/fuse/inode.c
    @@ -402,11 +402,6 @@ static void fuse_put_super(struct super_
    {
    struct fuse_conn *fc = get_fuse_conn_super(sb);

    - fuse_send_destroy(fc);
    -
    - fuse_abort_conn(fc);
    - fuse_wait_aborted(fc);
    -
    mutex_lock(&fuse_mutex);
    list_del(&fc->entry);
    fuse_ctl_remove_conn(fc);
    @@ -1206,16 +1201,25 @@ static struct dentry *fuse_mount(struct
    return mount_nodev(fs_type, flags, raw_data, fuse_fill_super);
    }

    -static void fuse_kill_sb_anon(struct super_block *sb)
    +static void fuse_sb_destroy(struct super_block *sb)
    {
    struct fuse_conn *fc = get_fuse_conn_super(sb);

    if (fc) {
    + fuse_send_destroy(fc);
    +
    + fuse_abort_conn(fc);
    + fuse_wait_aborted(fc);
    +
    down_write(&fc->killsb);
    fc->sb = NULL;
    up_write(&fc->killsb);
    }
    +}

    +static void fuse_kill_sb_anon(struct super_block *sb)
    +{
    + fuse_sb_destroy(sb);
    kill_anon_super(sb);
    }

    @@ -1238,14 +1242,7 @@ static struct dentry *fuse_mount_blk(str

    static void fuse_kill_sb_blk(struct super_block *sb)
    {
    - struct fuse_conn *fc = get_fuse_conn_super(sb);
    -
    - if (fc) {
    - down_write(&fc->killsb);
    - fc->sb = NULL;
    - up_write(&fc->killsb);
    - }
    -
    + fuse_sb_destroy(sb);
    kill_block_super(sb);
    }


    \
     
     \ /
      Last update: 2018-09-03 19:08    [W:4.127 / U:0.816 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site