Current we only do chunk validation check at mount time.
It's good for most case, but for fuzzed or manually crafted images, we
can insert a CHUNK_ITEM key into root tree.
Since mount time check will only check chunk tree, it will not check
CHUNK_ITEM in root tree.
Even with previous key type check against leaf owner, it is still
possible to modify the leaf owner to by-pass it.
So we still need to check chunk validation before processing it.
Reported-by: Lukas Lueg <lukas.lueg@gmail.com>
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
int slot)
{
struct chunk_record *rec;
+ struct btrfs_chunk *chunk;
int ret = 0;
+ chunk = btrfs_item_ptr(eb, slot, struct btrfs_chunk);
+ /*
+ * Do extra check for this chunk item,
+ *
+ * It's still possible one can craft a leaf with CHUNK_ITEM, with
+ * wrong onwer(3) out of chunk tree, to pass both chunk tree check
+ * and owner<->key_type check.
+ */
+ ret = btrfs_check_chunk_valid(global_info->tree_root, eb, chunk, slot,
+ key->offset);
+ if (ret < 0) {
+ error("chunk(%llu, %llu) is not valid, ignore it",
+ key->offset, btrfs_chunk_length(eb, chunk));
+ return 0;
+ }
rec = btrfs_new_chunk_record(eb, key, slot);
ret = insert_cache_extent(chunk_cache, &rec->cache);
if (ret) {
* slot == -1: SYSTEM chunk
* return -EIO on error, otherwise return 0
*/
-static int btrfs_check_chunk_valid(struct btrfs_root *root,
- struct extent_buffer *leaf,
- struct btrfs_chunk *chunk,
- int slot, u64 logical)
+int btrfs_check_chunk_valid(struct btrfs_root *root,
+ struct extent_buffer *leaf,
+ struct btrfs_chunk *chunk,
+ int slot, u64 logical)
{
u64 length;
u64 stripe_len;
struct extent_buffer *eb,
struct btrfs_multi_bio *multi,
u64 stripe_len, u64 *raid_map);
+int btrfs_check_chunk_valid(struct btrfs_root *root,
+ struct extent_buffer *leaf,
+ struct btrfs_chunk *chunk,
+ int slot, u64 logical);
#endif