From 91001769cd33366d0d04b39df5888b48060318b1 Mon Sep 17 00:00:00 2001 From: Andreas Wellving Date: Mon, 4 Feb 2019 13:01:04 +0100 Subject: btrfs: CVE-2018-14610 btrfs: Check that each block group has corresponding chunk at mount time References: https://nvd.nist.gov/vuln/detail/CVE-2018-14610 https://patchwork.kernel.org/patch/10503415/ Change-Id: Iba74233aaa43870b1621ef2ab6a59f70e8a6667e Signed-off-by: Andreas Wellving --- patches/cve/4.14.x.scc | 1 + ...-that-each-block-group-has-corresponding-.patch | 89 ++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 patches/cve/CVE-2018-14610-btrfs-Check-that-each-block-group-has-corresponding-.patch diff --git a/patches/cve/4.14.x.scc b/patches/cve/4.14.x.scc index b459173..a2417c2 100644 --- a/patches/cve/4.14.x.scc +++ b/patches/cve/4.14.x.scc @@ -6,3 +6,4 @@ patch CVE-2018-14633-scsi-target-iscsi-Use-hex2bin-instead-of-a-re-implem.patch patch CVE-2018-17972-proc-restrict-kernel-stack-dumps-to-root.patch #CVEs fixed in 4.14.86: patch CVE-2018-13097-f2fs-fix-to-do-sanity-check-with-user_block_count.patch +patch CVE-2018-14610-btrfs-Check-that-each-block-group-has-corresponding-.patch diff --git a/patches/cve/CVE-2018-14610-btrfs-Check-that-each-block-group-has-corresponding-.patch b/patches/cve/CVE-2018-14610-btrfs-Check-that-each-block-group-has-corresponding-.patch new file mode 100644 index 0000000..c4afc0d --- /dev/null +++ b/patches/cve/CVE-2018-14610-btrfs-Check-that-each-block-group-has-corresponding-.patch @@ -0,0 +1,89 @@ +From 34407a175a59b668a1a2bbf0d0e495d87a7777d8 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Wed, 1 Aug 2018 10:37:16 +0800 +Subject: [PATCH] btrfs: Check that each block group has corresponding chunk at + mount time + +commit 514c7dca85a0bf40be984dab0b477403a6db901f upstream. + +A crafted btrfs image with incorrect chunk<->block group mapping will +trigger a lot of unexpected things as the mapping is essential. + +Although the problem can be caught by block group item checker +added in "btrfs: tree-checker: Verify block_group_item", it's still not +sufficient. A sufficiently valid block group item can pass the check +added by the mentioned patch but could fail to match the existing chunk. + +This patch will add extra block group -> chunk mapping check, to ensure +we have a completely matching (start, len, flags) chunk for each block +group at mount time. + +Here we reuse the original helper find_first_block_group(), which is +already doing the basic bg -> chunk checks, adding further checks of the +start/len and type flags. + +CVE: CVE-2018-14610 +Upstream-Status: Backport + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=199837 +Reported-by: Xu Wen +Signed-off-by: Qu Wenruo +Reviewed-by: Su Yue +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Ben Hutchings +Signed-off-by: Sasha Levin +Signed-off-by: Andreas Wellving +--- + fs/btrfs/extent-tree.c | 28 +++++++++++++++++++++++++++- + 1 file changed, 27 insertions(+), 1 deletion(-) + +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index fdc42eddccc2..83791d13c204 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -9828,6 +9828,8 @@ static int find_first_block_group(struct btrfs_fs_info *fs_info, + int ret = 0; + struct btrfs_key found_key; + struct extent_buffer *leaf; ++ struct btrfs_block_group_item bg; ++ u64 flags; + int slot; + + ret = btrfs_search_slot(NULL, root, key, path, 0, 0); +@@ -9862,8 +9864,32 @@ static int find_first_block_group(struct btrfs_fs_info *fs_info, + "logical %llu len %llu found bg but no related chunk", + found_key.objectid, found_key.offset); + ret = -ENOENT; ++ } else if (em->start != found_key.objectid || ++ em->len != found_key.offset) { ++ btrfs_err(fs_info, ++ "block group %llu len %llu mismatch with chunk %llu len %llu", ++ found_key.objectid, found_key.offset, ++ em->start, em->len); ++ ret = -EUCLEAN; + } else { +- ret = 0; ++ read_extent_buffer(leaf, &bg, ++ btrfs_item_ptr_offset(leaf, slot), ++ sizeof(bg)); ++ flags = btrfs_block_group_flags(&bg) & ++ BTRFS_BLOCK_GROUP_TYPE_MASK; ++ ++ if (flags != (em->map_lookup->type & ++ BTRFS_BLOCK_GROUP_TYPE_MASK)) { ++ btrfs_err(fs_info, ++"block group %llu len %llu type flags 0x%llx mismatch with chunk type flags 0x%llx", ++ found_key.objectid, ++ found_key.offset, flags, ++ (BTRFS_BLOCK_GROUP_TYPE_MASK & ++ em->map_lookup->type)); ++ ret = -EUCLEAN; ++ } else { ++ ret = 0; ++ } + } + free_extent_map(em); + goto out; +-- +2.19.2 \ No newline at end of file -- cgit v1.2.3-54-g00ecf