From patchwork Fri Aug 31 02:29:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 10583057 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5DD9A5A4 for ; Fri, 31 Aug 2018 02:29:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4FD8C2C384 for ; Fri, 31 Aug 2018 02:29:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 446392C388; Fri, 31 Aug 2018 02:29:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ED8B42C384 for ; Fri, 31 Aug 2018 02:29:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727173AbeHaGfB (ORCPT ); Fri, 31 Aug 2018 02:35:01 -0400 Received: from mx2.suse.de ([195.135.220.15]:55758 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726037AbeHaGfB (ORCPT ); Fri, 31 Aug 2018 02:35:01 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id E0A57B05B for ; Fri, 31 Aug 2018 02:29:51 +0000 (UTC) From: Qu Wenruo To: linux-btrfs@vger.kernel.org Subject: [PATCH 1/3] btrfs: Set qgroup inherit size limit to SZ_4K instead of page size Date: Fri, 31 Aug 2018 10:29:28 +0800 Message-Id: <20180831022930.3465-2-wqu@suse.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180831022930.3465-1-wqu@suse.com> References: <20180831022930.3465-1-wqu@suse.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Change btrfs_qgroup_inherit maximum size from PAGE_SIZE to SZ_4K to make it consistent across different architectures. Although in theory this could lead to incompatibility, but considering how rare btrfs_qgroup_inherit is used, it's still not too late to change it without impacting a large user base. Signed-off-by: Qu Wenruo --- fs/btrfs/ioctl.c | 2 +- include/uapi/linux/btrfs.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 63600dc2ac4c..5db8680b40a9 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1811,7 +1811,7 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file, if (vol_args->flags & BTRFS_SUBVOL_RDONLY) readonly = true; if (vol_args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) { - if (vol_args->size > PAGE_SIZE) { + if (vol_args->size > BTRFS_QGROUP_INHERIT_MAX_SIZE) { ret = -EINVAL; goto free_args; } diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index 5ca1d21fc4a7..311edb65567c 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h @@ -82,6 +82,7 @@ struct btrfs_qgroup_limit { */ #define BTRFS_QGROUP_INHERIT_SET_LIMITS (1ULL << 0) +#define BTRFS_QGROUP_INHERIT_MAX_SIZE (SZ_4K) struct btrfs_qgroup_inherit { __u64 flags; __u64 num_qgroups; From patchwork Fri Aug 31 02:29:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 10583059 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BD90014BD for ; Fri, 31 Aug 2018 02:30:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ADD7D2C388 for ; Fri, 31 Aug 2018 02:30:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A203B2C386; Fri, 31 Aug 2018 02:30:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 24DA12C386 for ; Fri, 31 Aug 2018 02:30:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727232AbeHaGfH (ORCPT ); Fri, 31 Aug 2018 02:35:07 -0400 Received: from mx2.suse.de ([195.135.220.15]:55814 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726037AbeHaGfH (ORCPT ); Fri, 31 Aug 2018 02:35:07 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 1C796B062 for ; Fri, 31 Aug 2018 02:29:57 +0000 (UTC) From: Qu Wenruo To: linux-btrfs@vger.kernel.org Subject: [PATCH 2/3] btrfs: qgroup: Validate btrfs_qgroup_inherit structure before passing it to qgroup Date: Fri, 31 Aug 2018 10:29:29 +0800 Message-Id: <20180831022930.3465-3-wqu@suse.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180831022930.3465-1-wqu@suse.com> References: <20180831022930.3465-1-wqu@suse.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP btrfs_qgroup_inherit structure doesn't goes through much validation check. Now do a comprehensive check for it, including: 1) inherit size Should not exceeding SZ_4K and its num_qgroups should not exceed its size passed in btrfs_ioctl_vol_args_v2. 2) flags Should not include any unknown flags (In fact, no flag is supported at all now) Btrfs-progs never has such ability to set flags for btrfs_qgroup_inherit. 3) limit Should not contain anything. Btrfs-progs never has such ability to set limit for btrfs_qgroup_inherit. 4) rfer/excl copy Deprecated feature. Btrfs-progs has such interface but never documented and we're already going to remove such ability. It's the easiest way to screw up qgroup numbers. 3) Qgroupid Comprehensive check is already in btrfs_qgroup_inherit(), here we only check if there is any obviously invalid qgroupid (0). Coverity-id: 1021055 Reported-by: Nikolay Borisov Signed-off-by: Qu Wenruo --- fs/btrfs/ioctl.c | 3 +++ fs/btrfs/qgroup.c | 39 ++++++++++++++++++++++++++++++++++++++ fs/btrfs/qgroup.h | 2 ++ include/uapi/linux/btrfs.h | 17 ++++++++--------- 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 5db8680b40a9..4f5f453d5d07 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1820,6 +1820,9 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file, ret = PTR_ERR(inherit); goto free_args; } + ret = btrfs_validate_inherit(inherit, vol_args->size); + if (ret < 0) + goto free_args; } ret = btrfs_ioctl_snap_create_transid(file, vol_args->name, diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 4353bb69bb86..53daf73b0de9 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -2232,6 +2232,45 @@ int btrfs_run_qgroups(struct btrfs_trans_handle *trans) return ret; } +/* + * To make sure the inherit passed in is valid + * + * Here we only check flags and rule out some no-longer supported features. + * And we only do very basis qgroupid check to ensure there is no obviously + * invalid qgroupid (0). Detailed qgroupid check will be done in + * btrfs_qgroup_inherit(). + */ +int btrfs_validate_inherit(struct btrfs_qgroup_inherit *inherit, + u64 inherit_size) +{ + u64 i; + + if (inherit->flags & ~BTRFS_QGROUP_INHERIT_FLAGS_SUPP) + return -ENOTTY; + /* Qgroup rfer/excl copy is deprecated */ + if (inherit->num_excl_copies || inherit->num_ref_copies) + return -ENOTTY; + + /* Since SET_LIMITS is never used, @lim should all be zeroed */ + if (inherit->lim.max_excl || inherit->lim.max_rfer || + inherit->lim.rsv_excl || inherit->lim.rsv_rfer || + inherit->lim.flags) + return -ENOTTY; + + /* Size check */ + if (sizeof(u64) * inherit->num_qgroups + sizeof(*inherit) > + min_t(u64, BTRFS_QGROUP_INHERIT_MAX_SIZE, inherit_size)) + return -EINVAL; + + + /* Qgroup 0/0 is not allowed */ + for (i = 0; i < inherit->num_qgroups; i++) { + if (inherit->qgroups[i] == 0) + return -EINVAL; + } + return 0; +} + /* * Copy the accounting information between qgroups. This is necessary * when a snapshot or a subvolume is created. Throwing an error will diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h index 54b8bb282c0e..1bf9c584be70 100644 --- a/fs/btrfs/qgroup.h +++ b/fs/btrfs/qgroup.h @@ -241,6 +241,8 @@ int btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, u64 bytenr, struct ulist *new_roots); int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans); int btrfs_run_qgroups(struct btrfs_trans_handle *trans); +int btrfs_validate_inherit(struct btrfs_qgroup_inherit *inherit, + u64 inherit_size); int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid, u64 objectid, struct btrfs_qgroup_inherit *inherit); void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info, diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index 311edb65567c..5a5532a20019 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h @@ -74,21 +74,20 @@ struct btrfs_qgroup_limit { __u64 rsv_excl; }; -/* - * flags definition for qgroup inheritance - * - * Used by: - * struct btrfs_qgroup_inherit.flags - */ +/* flags definition for qgroup inheritance (DEPRECATED) */ #define BTRFS_QGROUP_INHERIT_SET_LIMITS (1ULL << 0) +/* No supported flags */ +#define BTRFS_QGROUP_INHERIT_FLAGS_SUPP (0) + #define BTRFS_QGROUP_INHERIT_MAX_SIZE (SZ_4K) + struct btrfs_qgroup_inherit { __u64 flags; __u64 num_qgroups; - __u64 num_ref_copies; - __u64 num_excl_copies; - struct btrfs_qgroup_limit lim; + __u64 num_ref_copies; /* DEPRECATED */ + __u64 num_excl_copies; /* DEPRECATED */ + struct btrfs_qgroup_limit lim; /* DEPRECATED */ __u64 qgroups[0]; }; From patchwork Fri Aug 31 02:29:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 10583061 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 68E49920 for ; Fri, 31 Aug 2018 02:30:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 583252C3E6 for ; Fri, 31 Aug 2018 02:30:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 55F5A2C45E; Fri, 31 Aug 2018 02:30:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ECD642C3F3 for ; Fri, 31 Aug 2018 02:30:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727247AbeHaGfO (ORCPT ); Fri, 31 Aug 2018 02:35:14 -0400 Received: from mx2.suse.de ([195.135.220.15]:55864 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726037AbeHaGfO (ORCPT ); Fri, 31 Aug 2018 02:35:14 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id DA412B060 for ; Fri, 31 Aug 2018 02:30:04 +0000 (UTC) From: Qu Wenruo To: linux-btrfs@vger.kernel.org Subject: [PATCH 3/3] btrfs: qgroup: Remove deprecated feature support in btrfs_qgorup_inhert() Date: Fri, 31 Aug 2018 10:29:30 +0800 Message-Id: <20180831022930.3465-4-wqu@suse.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180831022930.3465-1-wqu@suse.com> References: <20180831022930.3465-1-wqu@suse.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Since btrfs_validate_inherit() will not allow features like copy rfer/excl and limit set, remove these dead code. Signed-off-by: Qu Wenruo Reviewed-by: Omar Sandoval --- fs/btrfs/qgroup.c | 57 +---------------------------------------------- 1 file changed, 1 insertion(+), 56 deletions(-) diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 53daf73b0de9..b57577f45ff3 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -2301,8 +2301,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid, if (inherit) { i_qgroups = (u64 *)(inherit + 1); - nums = inherit->num_qgroups + 2 * inherit->num_ref_copies + - 2 * inherit->num_excl_copies; + nums = inherit->num_qgroups; for (i = 0; i < nums; ++i) { srcgroup = find_qgroup_rb(fs_info, *i_qgroups); @@ -2354,23 +2353,6 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid, goto unlock; } - if (inherit && inherit->flags & BTRFS_QGROUP_INHERIT_SET_LIMITS) { - dstgroup->lim_flags = inherit->lim.flags; - dstgroup->max_rfer = inherit->lim.max_rfer; - dstgroup->max_excl = inherit->lim.max_excl; - dstgroup->rsv_rfer = inherit->lim.rsv_rfer; - dstgroup->rsv_excl = inherit->lim.rsv_excl; - - ret = update_qgroup_limit_item(trans, dstgroup); - if (ret) { - fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT; - btrfs_info(fs_info, - "unable to update quota limit for %llu", - dstgroup->qgroupid); - goto unlock; - } - } - if (srcid) { srcgroup = find_qgroup_rb(fs_info, srcid); if (!srcgroup) @@ -2413,43 +2395,6 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid, ++i_qgroups; } - for (i = 0; i < inherit->num_ref_copies; ++i, i_qgroups += 2) { - struct btrfs_qgroup *src; - struct btrfs_qgroup *dst; - - if (!i_qgroups[0] || !i_qgroups[1]) - continue; - - src = find_qgroup_rb(fs_info, i_qgroups[0]); - dst = find_qgroup_rb(fs_info, i_qgroups[1]); - - if (!src || !dst) { - ret = -EINVAL; - goto unlock; - } - - dst->rfer = src->rfer - level_size; - dst->rfer_cmpr = src->rfer_cmpr - level_size; - } - for (i = 0; i < inherit->num_excl_copies; ++i, i_qgroups += 2) { - struct btrfs_qgroup *src; - struct btrfs_qgroup *dst; - - if (!i_qgroups[0] || !i_qgroups[1]) - continue; - - src = find_qgroup_rb(fs_info, i_qgroups[0]); - dst = find_qgroup_rb(fs_info, i_qgroups[1]); - - if (!src || !dst) { - ret = -EINVAL; - goto unlock; - } - - dst->excl = src->excl + level_size; - dst->excl_cmpr = src->excl_cmpr + level_size; - } - unlock: spin_unlock(&fs_info->qgroup_lock); out: