Received: by 2002:a05:6a10:6744:0:0:0:0 with SMTP id w4csp5877966pxu; Thu, 22 Oct 2020 13:26:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy3Wl/7siRDPDN4IXXebE2cieHlACVsienH8SXaTSWTihsO7XWnccQKxSGURvG27pfnQl6V X-Received: by 2002:a17:906:580e:: with SMTP id m14mr3881917ejq.237.1603398374415; Thu, 22 Oct 2020 13:26:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1603398374; cv=none; d=google.com; s=arc-20160816; b=yVjPPOCkdSJ/lSr2klFVG3PY/JuDNlwDmUwI08ZZAILHE52yJpFebGMn8BiN3Xk93N r2KkH6qGS5SIvKFU7uskKq1ZmkCriw69L0bf1CHcZrWYUBSn7nixlb2GvqhWmVvYQ1RO zSIgAj4rqzGz0OEX3d0zRpdNamPE5mzkoMSRuPEnI2+dlNT9d3kP6g4ZcSn6OhMPNNYy p1J+fzMJfCTsrN98SWGX0ZbF+L88vchWj/7iJG5SW2A4ifUkQZzYFv8Ptpg42bWosrmc ocwpRfyq2ZWpJgHvscTEB17fgDQu3+FCEw9nnYp/kfq8TNYG8AcrmMuYa9u0Ysl3Eku+ UbiA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:content-language :mime-version:user-agent:date:message-id:subject:from:cc:to; bh=os7n/WQ/IIu5ypiRprcG5gt6tkbi1VGwBCuRtCo3lQU=; b=AgnSdAzpdnYo8JrdyyC3FJDBtyimhpDcZTsb3LsSDUWmDTkAgyVdE07W+ChnEtI3fS HI1JZzCY1KDwYLpf9xNSuCFbuDyJOa3uJPcZsRYfiHWqD3eEQwgJ+N2Zp+bi8a+CjOjo lNVryZDtqNhAyGlCvDJwBYAS7qOx5ArtkkahzuQdepd1/yptD4xZpbOCfZgW6QFETnJ9 o7PebdIlgGl0V6Dm9slTy3zCCuE4BDlZnXauIYYXIGnhvOh4ilTjlaoW9s5vwxxXREn4 zlH19+G5XJ76m+Fr+NgerBwWpb138CYRuHaD9BckU7w2Y/v64BelJRk+JwQzoQaoTM8l fFOw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id m4si1632213edv.101.2020.10.22.13.25.51; Thu, 22 Oct 2020 13:26:14 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S368220AbgJVOwJ (ORCPT + 99 others); Thu, 22 Oct 2020 10:52:09 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:15245 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S368214AbgJVOwJ (ORCPT ); Thu, 22 Oct 2020 10:52:09 -0400 Received: from DGGEMS404-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 30F26FF6DDC4680DAA83; Thu, 22 Oct 2020 22:52:04 +0800 (CST) Received: from [127.0.0.1] (10.174.176.238) by DGGEMS404-HUB.china.huawei.com (10.3.19.204) with Microsoft SMTP Server id 14.3.487.0; Thu, 22 Oct 2020 22:51:54 +0800 To: , CC: linfeilong , , "linux-kernel@vger.kernel.org" , lihaotian , From: Zhiqiang Liu Subject: [PATCH] fuse: fix potential accessing NULL pointer problem in fuse_send_init() Message-ID: <5e1bf70a-0c6b-89b6-dc9f-474ccfcfe597@huawei.com> Date: Thu, 22 Oct 2020 22:51:53 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Language: en-US Content-Transfer-Encoding: 7bit X-Originating-IP: [10.174.176.238] X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In fuse_send_init func, ia is allocated by calling kzalloc func, and we donot check whether ia is NULL before using it. Thus, if allocating ia fails, accessing NULL pointer problem will occur. Here, we will call process_init_reply func if ia is NULL. Fixes: 615047eff108 ("fuse: convert init to simple api") Signed-off-by: Zhiqiang Liu Signed-off-by: Haotian Li --- fs/fuse/inode.c | 161 ++++++++++++++++++++++++++---------------------- 1 file changed, 87 insertions(+), 74 deletions(-) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 581329203d68..bb526d8cf5b0 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -898,88 +898,97 @@ struct fuse_init_args { static void process_init_reply(struct fuse_conn *fc, struct fuse_args *args, int error) { - struct fuse_init_args *ia = container_of(args, typeof(*ia), args); - struct fuse_init_out *arg = &ia->out; + struct fuse_init_args *ia; + struct fuse_init_out *arg; + unsigned long ra_pages; - if (error || arg->major != FUSE_KERNEL_VERSION) + if (!args) { fc->conn_error = 1; - else { - unsigned long ra_pages; + goto out; + } - process_init_limits(fc, arg); + ia = container_of(args, typeof(*ia), args); + arg = &ia->out; + if (error || arg->major != FUSE_KERNEL_VERSION) { + fc->conn_error = 1; + goto out_free_ia; + } - if (arg->minor >= 6) { - ra_pages = arg->max_readahead / PAGE_SIZE; - if (arg->flags & FUSE_ASYNC_READ) - fc->async_read = 1; - if (!(arg->flags & FUSE_POSIX_LOCKS)) - fc->no_lock = 1; - if (arg->minor >= 17) { - if (!(arg->flags & FUSE_FLOCK_LOCKS)) - fc->no_flock = 1; - } else { - if (!(arg->flags & FUSE_POSIX_LOCKS)) - fc->no_flock = 1; - } - if (arg->flags & FUSE_ATOMIC_O_TRUNC) - fc->atomic_o_trunc = 1; - if (arg->minor >= 9) { - /* LOOKUP has dependency on proto version */ - if (arg->flags & FUSE_EXPORT_SUPPORT) - fc->export_support = 1; - } - if (arg->flags & FUSE_BIG_WRITES) - fc->big_writes = 1; - if (arg->flags & FUSE_DONT_MASK) - fc->dont_mask = 1; - if (arg->flags & FUSE_AUTO_INVAL_DATA) - fc->auto_inval_data = 1; - else if (arg->flags & FUSE_EXPLICIT_INVAL_DATA) - fc->explicit_inval_data = 1; - if (arg->flags & FUSE_DO_READDIRPLUS) { - fc->do_readdirplus = 1; - if (arg->flags & FUSE_READDIRPLUS_AUTO) - fc->readdirplus_auto = 1; - } - if (arg->flags & FUSE_ASYNC_DIO) - fc->async_dio = 1; - if (arg->flags & FUSE_WRITEBACK_CACHE) - fc->writeback_cache = 1; - if (arg->flags & FUSE_PARALLEL_DIROPS) - fc->parallel_dirops = 1; - if (arg->flags & FUSE_HANDLE_KILLPRIV) - fc->handle_killpriv = 1; - if (arg->time_gran && arg->time_gran <= 1000000000) - fc->sb->s_time_gran = arg->time_gran; - if ((arg->flags & FUSE_POSIX_ACL)) { - fc->default_permissions = 1; - fc->posix_acl = 1; - fc->sb->s_xattr = fuse_acl_xattr_handlers; - } - if (arg->flags & FUSE_CACHE_SYMLINKS) - fc->cache_symlinks = 1; - if (arg->flags & FUSE_ABORT_ERROR) - fc->abort_err = 1; - if (arg->flags & FUSE_MAX_PAGES) { - fc->max_pages = - min_t(unsigned int, FUSE_MAX_MAX_PAGES, - max_t(unsigned int, arg->max_pages, 1)); - } - } else { - ra_pages = fc->max_read / PAGE_SIZE; + process_init_limits(fc, arg); + + if (arg->minor >= 6) { + ra_pages = arg->max_readahead / PAGE_SIZE; + if (arg->flags & FUSE_ASYNC_READ) + fc->async_read = 1; + if (!(arg->flags & FUSE_POSIX_LOCKS)) fc->no_lock = 1; - fc->no_flock = 1; + if (arg->minor >= 17) { + if (!(arg->flags & FUSE_FLOCK_LOCKS)) + fc->no_flock = 1; + } else { + if (!(arg->flags & FUSE_POSIX_LOCKS)) + fc->no_flock = 1; } - - fc->sb->s_bdi->ra_pages = - min(fc->sb->s_bdi->ra_pages, ra_pages); - fc->minor = arg->minor; - fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; - fc->max_write = max_t(unsigned, 4096, fc->max_write); - fc->conn_init = 1; + if (arg->flags & FUSE_ATOMIC_O_TRUNC) + fc->atomic_o_trunc = 1; + if (arg->minor >= 9) { + /* LOOKUP has dependency on proto version */ + if (arg->flags & FUSE_EXPORT_SUPPORT) + fc->export_support = 1; + } + if (arg->flags & FUSE_BIG_WRITES) + fc->big_writes = 1; + if (arg->flags & FUSE_DONT_MASK) + fc->dont_mask = 1; + if (arg->flags & FUSE_AUTO_INVAL_DATA) + fc->auto_inval_data = 1; + else if (arg->flags & FUSE_EXPLICIT_INVAL_DATA) + fc->explicit_inval_data = 1; + if (arg->flags & FUSE_DO_READDIRPLUS) { + fc->do_readdirplus = 1; + if (arg->flags & FUSE_READDIRPLUS_AUTO) + fc->readdirplus_auto = 1; + } + if (arg->flags & FUSE_ASYNC_DIO) + fc->async_dio = 1; + if (arg->flags & FUSE_WRITEBACK_CACHE) + fc->writeback_cache = 1; + if (arg->flags & FUSE_PARALLEL_DIROPS) + fc->parallel_dirops = 1; + if (arg->flags & FUSE_HANDLE_KILLPRIV) + fc->handle_killpriv = 1; + if (arg->time_gran && arg->time_gran <= 1000000000) + fc->sb->s_time_gran = arg->time_gran; + if ((arg->flags & FUSE_POSIX_ACL)) { + fc->default_permissions = 1; + fc->posix_acl = 1; + fc->sb->s_xattr = fuse_acl_xattr_handlers; + } + if (arg->flags & FUSE_CACHE_SYMLINKS) + fc->cache_symlinks = 1; + if (arg->flags & FUSE_ABORT_ERROR) + fc->abort_err = 1; + if (arg->flags & FUSE_MAX_PAGES) { + fc->max_pages = + min_t(unsigned int, FUSE_MAX_MAX_PAGES, + max_t(unsigned int, arg->max_pages, 1)); + } + } else { + ra_pages = fc->max_read / PAGE_SIZE; + fc->no_lock = 1; + fc->no_flock = 1; } - kfree(ia); + fc->sb->s_bdi->ra_pages = + min(fc->sb->s_bdi->ra_pages, ra_pages); + fc->minor = arg->minor; + fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; + fc->max_write = max_t(unsigned int, 4096, fc->max_write); + fc->conn_init = 1; + +out_free_ia: + kfree(ia); +out: fuse_set_initialized(fc); wake_up_all(&fc->blocked_waitq); } @@ -989,6 +998,10 @@ void fuse_send_init(struct fuse_conn *fc) struct fuse_init_args *ia; ia = kzalloc(sizeof(*ia), GFP_KERNEL | __GFP_NOFAIL); + if (!ia) { + process_init_reply(fc, NULL, -ENOTCONN); + return; + } ia->in.major = FUSE_KERNEL_VERSION; ia->in.minor = FUSE_KERNEL_MINOR_VERSION; -- 2.19.1