linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Xu Wen <wen.xu@gatech.edu>,
	Qu Wenruo <wqu@suse.com>, Gu Jinxiang <gujx@cn.fujitsu.com>,
	Nikolay Borisov <nborisov@suse.com>,
	David Sterba <dsterba@suse.com>,
	Ben Hutchings <ben.hutchings@codethink.co.uk>
Subject: [PATCH 4.4 26/51] btrfs: tree-checker: Verify block_group_item
Date: Tue, 15 Jan 2019 17:35:22 +0100	[thread overview]
Message-ID: <20190115154850.401370379@linuxfoundation.org> (raw)
In-Reply-To: <20190115154846.928796000@linuxfoundation.org>

4.4-stable review patch.  If anyone has any objections, please let me know.

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

From: Qu Wenruo <wqu@suse.com>

commit fce466eab7ac6baa9d2dcd88abcf945be3d4a089 upstream.

A crafted image with invalid block group items could make free space cache
code to cause panic.

We could detect such invalid block group item by checking:
1) Item size
   Known fixed value.
2) Block group size (key.offset)
   We have an upper limit on block group item (10G)
3) Chunk objectid
   Known fixed value.
4) Type
   Only 4 valid type values, DATA, METADATA, SYSTEM and DATA|METADATA.
   No more than 1 bit set for profile type.
5) Used space
   No more than the block group size.

This should allow btrfs to detect and refuse to mount the crafted image.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=199849
Reported-by: Xu Wen <wen.xu@gatech.edu>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Gu Jinxiang <gujx@cn.fujitsu.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Tested-by: Gu Jinxiang <gujx@cn.fujitsu.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
[bwh: Backported to 4.4:
 - In check_leaf_item(), pass root->fs_info to check_block_group_item()
 - Include <linux/sizes.h> (in ctree.h, to match upstream)
 - Adjust context]
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/btrfs/ctree.h        |    1 
 fs/btrfs/tree-checker.c |  100 ++++++++++++++++++++++++++++++++++++++++++++++++
 fs/btrfs/volumes.c      |    2 
 fs/btrfs/volumes.h      |    2 
 4 files changed, 104 insertions(+), 1 deletion(-)

--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -35,6 +35,7 @@
 #include <linux/btrfs.h>
 #include <linux/workqueue.h>
 #include <linux/security.h>
+#include <linux/sizes.h>
 #include "extent_io.h"
 #include "extent_map.h"
 #include "async-thread.h"
--- a/fs/btrfs/tree-checker.c
+++ b/fs/btrfs/tree-checker.c
@@ -31,6 +31,7 @@
 #include "disk-io.h"
 #include "compression.h"
 #include "hash.h"
+#include "volumes.h"
 
 #define CORRUPT(reason, eb, root, slot)					\
 	btrfs_crit(root->fs_info,					\
@@ -312,6 +313,102 @@ static int check_dir_item(struct btrfs_r
 	return 0;
 }
 
+__printf(4, 5)
+__cold
+static void block_group_err(const struct btrfs_fs_info *fs_info,
+			    const struct extent_buffer *eb, int slot,
+			    const char *fmt, ...)
+{
+	struct btrfs_key key;
+	struct va_format vaf;
+	va_list args;
+
+	btrfs_item_key_to_cpu(eb, &key, slot);
+	va_start(args, fmt);
+
+	vaf.fmt = fmt;
+	vaf.va = &args;
+
+	btrfs_crit(fs_info,
+	"corrupt %s: root=%llu block=%llu slot=%d bg_start=%llu bg_len=%llu, %pV",
+		btrfs_header_level(eb) == 0 ? "leaf" : "node",
+		btrfs_header_owner(eb), btrfs_header_bytenr(eb), slot,
+		key.objectid, key.offset, &vaf);
+	va_end(args);
+}
+
+static int check_block_group_item(struct btrfs_fs_info *fs_info,
+				  struct extent_buffer *leaf,
+				  struct btrfs_key *key, int slot)
+{
+	struct btrfs_block_group_item bgi;
+	u32 item_size = btrfs_item_size_nr(leaf, slot);
+	u64 flags;
+	u64 type;
+
+	/*
+	 * Here we don't really care about alignment since extent allocator can
+	 * handle it.  We care more about the size, as if one block group is
+	 * larger than maximum size, it's must be some obvious corruption.
+	 */
+	if (key->offset > BTRFS_MAX_DATA_CHUNK_SIZE || key->offset == 0) {
+		block_group_err(fs_info, leaf, slot,
+			"invalid block group size, have %llu expect (0, %llu]",
+				key->offset, BTRFS_MAX_DATA_CHUNK_SIZE);
+		return -EUCLEAN;
+	}
+
+	if (item_size != sizeof(bgi)) {
+		block_group_err(fs_info, leaf, slot,
+			"invalid item size, have %u expect %zu",
+				item_size, sizeof(bgi));
+		return -EUCLEAN;
+	}
+
+	read_extent_buffer(leaf, &bgi, btrfs_item_ptr_offset(leaf, slot),
+			   sizeof(bgi));
+	if (btrfs_block_group_chunk_objectid(&bgi) !=
+	    BTRFS_FIRST_CHUNK_TREE_OBJECTID) {
+		block_group_err(fs_info, leaf, slot,
+		"invalid block group chunk objectid, have %llu expect %llu",
+				btrfs_block_group_chunk_objectid(&bgi),
+				BTRFS_FIRST_CHUNK_TREE_OBJECTID);
+		return -EUCLEAN;
+	}
+
+	if (btrfs_block_group_used(&bgi) > key->offset) {
+		block_group_err(fs_info, leaf, slot,
+			"invalid block group used, have %llu expect [0, %llu)",
+				btrfs_block_group_used(&bgi), key->offset);
+		return -EUCLEAN;
+	}
+
+	flags = btrfs_block_group_flags(&bgi);
+	if (hweight64(flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) > 1) {
+		block_group_err(fs_info, leaf, slot,
+"invalid profile flags, have 0x%llx (%lu bits set) expect no more than 1 bit set",
+			flags & BTRFS_BLOCK_GROUP_PROFILE_MASK,
+			hweight64(flags & BTRFS_BLOCK_GROUP_PROFILE_MASK));
+		return -EUCLEAN;
+	}
+
+	type = flags & BTRFS_BLOCK_GROUP_TYPE_MASK;
+	if (type != BTRFS_BLOCK_GROUP_DATA &&
+	    type != BTRFS_BLOCK_GROUP_METADATA &&
+	    type != BTRFS_BLOCK_GROUP_SYSTEM &&
+	    type != (BTRFS_BLOCK_GROUP_METADATA |
+			   BTRFS_BLOCK_GROUP_DATA)) {
+		block_group_err(fs_info, leaf, slot,
+"invalid type, have 0x%llx (%lu bits set) expect either 0x%llx, 0x%llx, 0x%llu or 0x%llx",
+			type, hweight64(type),
+			BTRFS_BLOCK_GROUP_DATA, BTRFS_BLOCK_GROUP_METADATA,
+			BTRFS_BLOCK_GROUP_SYSTEM,
+			BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA);
+		return -EUCLEAN;
+	}
+	return 0;
+}
+
 /*
  * Common point to switch the item-specific validation.
  */
@@ -333,6 +430,9 @@ static int check_leaf_item(struct btrfs_
 	case BTRFS_XATTR_ITEM_KEY:
 		ret = check_dir_item(root, leaf, key, slot);
 		break;
+	case BTRFS_BLOCK_GROUP_ITEM_KEY:
+		ret = check_block_group_item(root->fs_info, leaf, key, slot);
+		break;
 	}
 	return ret;
 }
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4540,7 +4540,7 @@ static int __btrfs_alloc_chunk(struct bt
 
 	if (type & BTRFS_BLOCK_GROUP_DATA) {
 		max_stripe_size = 1024 * 1024 * 1024;
-		max_chunk_size = 10 * max_stripe_size;
+		max_chunk_size = BTRFS_MAX_DATA_CHUNK_SIZE;
 		if (!devs_max)
 			devs_max = BTRFS_MAX_DEVS(info->chunk_root);
 	} else if (type & BTRFS_BLOCK_GROUP_METADATA) {
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -24,6 +24,8 @@
 #include <linux/btrfs.h>
 #include "async-thread.h"
 
+#define BTRFS_MAX_DATA_CHUNK_SIZE	(10ULL * SZ_1G)
+
 extern struct mutex uuid_mutex;
 
 #define BTRFS_STRIPE_LEN	(64 * 1024)



  parent reply	other threads:[~2019-01-15 16:37 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-15 16:34 [PATCH 4.4 00/51] 4.4.171-stable review Greg Kroah-Hartman
2019-01-15 16:34 ` [PATCH 4.4 01/51] ALSA: hda/realtek - Disable headset Mic VREF for headset mode of ALC225 Greg Kroah-Hartman
2019-01-15 16:34 ` [PATCH 4.4 02/51] btrfs: cleanup, stop casting for extent_map->lookup everywhere Greg Kroah-Hartman
2019-01-15 16:34 ` [PATCH 4.4 03/51] btrfs: Enhance chunk validation check Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 04/51] Btrfs: add validadtion checks for chunk loading Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 05/51] Btrfs: check inconsistence between chunk and block group Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 06/51] Btrfs: fix em leak in find_first_block_group Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 07/51] Btrfs: detect corruption when non-root leaf has zero item Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 08/51] Btrfs: check btree nodes nritems Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 09/51] Btrfs: fix BUG_ON in btrfs_mark_buffer_dirty Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 10/51] Btrfs: memset to avoid stale content in btree node block Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 11/51] Btrfs: improve check_node to avoid reading corrupted nodes Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 12/51] Btrfs: kill BUG_ON in run_delayed_tree_ref Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 13/51] Btrfs: memset to avoid stale content in btree leaf Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 14/51] Btrfs: fix emptiness check for dirtied extent buffers at check_leaf() Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 15/51] btrfs: struct-funcs, constify readers Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 16/51] btrfs: Refactor check_leaf function for later expansion Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 17/51] btrfs: Check if item pointer overlaps with the item itself Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 18/51] btrfs: Add sanity check for EXTENT_DATA when reading out leaf Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 19/51] btrfs: Add checker for EXTENT_CSUM Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 20/51] btrfs: Move leaf and node validation checker to tree-checker.c Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 21/51] btrfs: tree-checker: Enhance btrfs_check_node output Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 22/51] btrfs: tree-checker: Fix false panic for sanity test Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 23/51] btrfs: tree-checker: Add checker for dir item Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 24/51] btrfs: tree-checker: use %zu format string for size_t Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 25/51] btrfs: tree-check: reduce stack consumption in check_dir_item Greg Kroah-Hartman
2019-01-15 16:35 ` Greg Kroah-Hartman [this message]
2019-01-15 16:35 ` [PATCH 4.4 27/51] btrfs: tree-checker: Detect invalid and empty essential trees Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 28/51] btrfs: validate type when reading a chunk Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 29/51] btrfs: Check that each block group has corresponding chunk at mount time Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 30/51] btrfs: Verify that every chunk has corresponding block group " Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 31/51] btrfs: tree-checker: Check level for leaves and nodes Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 32/51] btrfs: tree-checker: Fix misleading group system information Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 33/51] CIFS: Do not hide EINTR after sending network packets Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 34/51] cifs: Fix potential OOB access of lock element array Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 35/51] usb: cdc-acm: send ZLP for Telit 3G Intel based modems Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 36/51] USB: storage: dont insert sane sense for SPC3+ when bad sense specified Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 37/51] USB: storage: add quirk for SMI SM3350 Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 38/51] USB: Add USB_QUIRK_DELAY_CTRL_MSG quirk for Corsair K70 RGB Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 39/51] slab: alien caches must not be initialized if the allocation of the alien cache failed Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 40/51] PCI: altera: Fix altera_pcie_link_is_up() Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 41/51] PCI: altera: Reorder read/write functions Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 42/51] PCI: altera: Check link status before retrain link Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 43/51] PCI: altera: Poll for link up status after retraining the link Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 44/51] PCI: altera: Poll for link training " Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 45/51] PCI: altera: Rework config accessors for use without a struct pci_bus Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 46/51] PCI: altera: Move retrain from fixup to altera_pcie_host_init() Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 47/51] ACPI: power: Skip duplicate power resource references in _PRx Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 48/51] i2c: dev: prevent adapter retries and timeout being set as minus value Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 49/51] crypto: cts - fix crash on short inputs Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 50/51] ext4: fix a potential fiemap/page fault deadlock w/ inline_data Greg Kroah-Hartman
2019-01-15 16:35 ` [PATCH 4.4 51/51] sunrpc: use-after-free in svc_process_common() Greg Kroah-Hartman
2019-01-16  1:24 ` [PATCH 4.4 00/51] 4.4.171-stable review shuah
2019-01-16 11:55 ` Naresh Kamboju
2019-01-16 20:36 ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190115154850.401370379@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=ben.hutchings@codethink.co.uk \
    --cc=dsterba@suse.com \
    --cc=gujx@cn.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nborisov@suse.com \
    --cc=stable@vger.kernel.org \
    --cc=wen.xu@gatech.edu \
    --cc=wqu@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).