@@ -6122,6 +6122,58 @@ full_backref:
return 0;
}
+static void report_mismatch_key_root(u8 key_type, u64 rootid)
+{
+ fprintf(stderr, "Invalid key type(");
+ print_key_type(stderr, 0, key_type);
+ fprintf(stderr, ") found in root(");
+ print_objectid(stderr, rootid, 0);
+ fprintf(stderr, ")\n");
+}
+
+/*
+ * Check if the key is valid with its extent buffer.
+ *
+ * This is a early check in case invalid key exists in a extent buffer
+ * This is not comprehensive yet, but should prevent wrong key/item passed
+ * further
+ */
+static int check_type_with_root(u64 rootid, u8 key_type)
+{
+ switch (key_type) {
+ /* Only valid in chunk tree */
+ case BTRFS_DEV_ITEM_KEY:
+ case BTRFS_CHUNK_ITEM_KEY:
+ if (rootid != BTRFS_CHUNK_TREE_OBJECTID)
+ goto err;
+ break;
+ /* valid in csum and log tree */
+ case BTRFS_CSUM_TREE_OBJECTID:
+ if (!(rootid == BTRFS_TREE_LOG_OBJECTID ||
+ is_fstree(rootid)))
+ goto err;
+ break;
+ case BTRFS_EXTENT_ITEM_KEY:
+ case BTRFS_METADATA_ITEM_KEY:
+ case BTRFS_BLOCK_GROUP_ITEM_KEY:
+ if (rootid != BTRFS_EXTENT_TREE_OBJECTID)
+ goto err;
+ break;
+ case BTRFS_ROOT_ITEM_KEY:
+ if (rootid != BTRFS_ROOT_TREE_OBJECTID)
+ goto err;
+ break;
+ case BTRFS_DEV_EXTENT_KEY:
+ if (rootid != BTRFS_DEV_TREE_OBJECTID)
+ goto err;
+ break;
+ }
+ return 0;
+err:
+ report_mismatch_key_root(key_type, rootid);
+ return -EINVAL;
+}
+
static int run_next_block(struct btrfs_root *root,
struct block_info *bits,
int bits_nr,
@@ -6271,6 +6323,16 @@ static int run_next_block(struct btrfs_root *root,
for (i = 0; i < nritems; i++) {
struct btrfs_file_extent_item *fi;
btrfs_item_key_to_cpu(buf, &key, i);
+ /*
+ * Check key type against the leaf owner.
+ * Could filter quite a lot of early error if
+ * owner is correct
+ */
+ if (check_type_with_root(btrfs_header_owner(buf),
+ key.type)) {
+ fprintf(stderr, "ignoring invalid key\n");
+ continue;
+ }
if (key.type == BTRFS_EXTENT_ITEM_KEY) {
process_extent_item(root, extent_cache, buf,
i);
Btrfs tree implies a lot of restriction on which key types are allowed in specific roots. Like CHUNK_ITEM keys are only valid in chunk root. This patch will add such check at run_next_block() for original mode. Reported-by: Lukas Lueg <lukas.lueg@gmail.com> Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> --- cmds-check.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+)