1*557ea5ddSQu Wenruo /* 2*557ea5ddSQu Wenruo * Copyright (C) Qu Wenruo 2017. All rights reserved. 3*557ea5ddSQu Wenruo * 4*557ea5ddSQu Wenruo * This program is free software; you can redistribute it and/or 5*557ea5ddSQu Wenruo * modify it under the terms of the GNU General Public 6*557ea5ddSQu Wenruo * License v2 as published by the Free Software Foundation. 7*557ea5ddSQu Wenruo * 8*557ea5ddSQu Wenruo * This program is distributed in the hope that it will be useful, 9*557ea5ddSQu Wenruo * but WITHOUT ANY WARRANTY; without even the implied warranty of 10*557ea5ddSQu Wenruo * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11*557ea5ddSQu Wenruo * General Public License for more details. 12*557ea5ddSQu Wenruo * 13*557ea5ddSQu Wenruo * You should have received a copy of the GNU General Public 14*557ea5ddSQu Wenruo * License along with this program. 15*557ea5ddSQu Wenruo */ 16*557ea5ddSQu Wenruo 17*557ea5ddSQu Wenruo /* 18*557ea5ddSQu Wenruo * The module is used to catch unexpected/corrupted tree block data. 19*557ea5ddSQu Wenruo * Such behavior can be caused either by a fuzzed image or bugs. 20*557ea5ddSQu Wenruo * 21*557ea5ddSQu Wenruo * The objective is to do leaf/node validation checks when tree block is read 22*557ea5ddSQu Wenruo * from disk, and check *every* possible member, so other code won't 23*557ea5ddSQu Wenruo * need to checking them again. 24*557ea5ddSQu Wenruo * 25*557ea5ddSQu Wenruo * Due to the potential and unwanted damage, every checker needs to be 26*557ea5ddSQu Wenruo * carefully reviewed otherwise so it does not prevent mount of valid images. 27*557ea5ddSQu Wenruo */ 28*557ea5ddSQu Wenruo 29*557ea5ddSQu Wenruo #include "ctree.h" 30*557ea5ddSQu Wenruo #include "tree-checker.h" 31*557ea5ddSQu Wenruo #include "disk-io.h" 32*557ea5ddSQu Wenruo #include "compression.h" 33*557ea5ddSQu Wenruo 34*557ea5ddSQu Wenruo #define CORRUPT(reason, eb, root, slot) \ 35*557ea5ddSQu Wenruo btrfs_crit(root->fs_info, \ 36*557ea5ddSQu Wenruo "corrupt %s, %s: block=%llu, root=%llu, slot=%d", \ 37*557ea5ddSQu Wenruo btrfs_header_level(eb) == 0 ? "leaf" : "node", \ 38*557ea5ddSQu Wenruo reason, btrfs_header_bytenr(eb), root->objectid, slot) 39*557ea5ddSQu Wenruo 40*557ea5ddSQu Wenruo static int check_extent_data_item(struct btrfs_root *root, 41*557ea5ddSQu Wenruo struct extent_buffer *leaf, 42*557ea5ddSQu Wenruo struct btrfs_key *key, int slot) 43*557ea5ddSQu Wenruo { 44*557ea5ddSQu Wenruo struct btrfs_file_extent_item *fi; 45*557ea5ddSQu Wenruo u32 sectorsize = root->fs_info->sectorsize; 46*557ea5ddSQu Wenruo u32 item_size = btrfs_item_size_nr(leaf, slot); 47*557ea5ddSQu Wenruo 48*557ea5ddSQu Wenruo if (!IS_ALIGNED(key->offset, sectorsize)) { 49*557ea5ddSQu Wenruo CORRUPT("unaligned key offset for file extent", 50*557ea5ddSQu Wenruo leaf, root, slot); 51*557ea5ddSQu Wenruo return -EUCLEAN; 52*557ea5ddSQu Wenruo } 53*557ea5ddSQu Wenruo 54*557ea5ddSQu Wenruo fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); 55*557ea5ddSQu Wenruo 56*557ea5ddSQu Wenruo if (btrfs_file_extent_type(leaf, fi) > BTRFS_FILE_EXTENT_TYPES) { 57*557ea5ddSQu Wenruo CORRUPT("invalid file extent type", leaf, root, slot); 58*557ea5ddSQu Wenruo return -EUCLEAN; 59*557ea5ddSQu Wenruo } 60*557ea5ddSQu Wenruo 61*557ea5ddSQu Wenruo /* 62*557ea5ddSQu Wenruo * Support for new compression/encrption must introduce incompat flag, 63*557ea5ddSQu Wenruo * and must be caught in open_ctree(). 64*557ea5ddSQu Wenruo */ 65*557ea5ddSQu Wenruo if (btrfs_file_extent_compression(leaf, fi) > BTRFS_COMPRESS_TYPES) { 66*557ea5ddSQu Wenruo CORRUPT("invalid file extent compression", leaf, root, slot); 67*557ea5ddSQu Wenruo return -EUCLEAN; 68*557ea5ddSQu Wenruo } 69*557ea5ddSQu Wenruo if (btrfs_file_extent_encryption(leaf, fi)) { 70*557ea5ddSQu Wenruo CORRUPT("invalid file extent encryption", leaf, root, slot); 71*557ea5ddSQu Wenruo return -EUCLEAN; 72*557ea5ddSQu Wenruo } 73*557ea5ddSQu Wenruo if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) { 74*557ea5ddSQu Wenruo /* Inline extent must have 0 as key offset */ 75*557ea5ddSQu Wenruo if (key->offset) { 76*557ea5ddSQu Wenruo CORRUPT("inline extent has non-zero key offset", 77*557ea5ddSQu Wenruo leaf, root, slot); 78*557ea5ddSQu Wenruo return -EUCLEAN; 79*557ea5ddSQu Wenruo } 80*557ea5ddSQu Wenruo 81*557ea5ddSQu Wenruo /* Compressed inline extent has no on-disk size, skip it */ 82*557ea5ddSQu Wenruo if (btrfs_file_extent_compression(leaf, fi) != 83*557ea5ddSQu Wenruo BTRFS_COMPRESS_NONE) 84*557ea5ddSQu Wenruo return 0; 85*557ea5ddSQu Wenruo 86*557ea5ddSQu Wenruo /* Uncompressed inline extent size must match item size */ 87*557ea5ddSQu Wenruo if (item_size != BTRFS_FILE_EXTENT_INLINE_DATA_START + 88*557ea5ddSQu Wenruo btrfs_file_extent_ram_bytes(leaf, fi)) { 89*557ea5ddSQu Wenruo CORRUPT("plaintext inline extent has invalid size", 90*557ea5ddSQu Wenruo leaf, root, slot); 91*557ea5ddSQu Wenruo return -EUCLEAN; 92*557ea5ddSQu Wenruo } 93*557ea5ddSQu Wenruo return 0; 94*557ea5ddSQu Wenruo } 95*557ea5ddSQu Wenruo 96*557ea5ddSQu Wenruo /* Regular or preallocated extent has fixed item size */ 97*557ea5ddSQu Wenruo if (item_size != sizeof(*fi)) { 98*557ea5ddSQu Wenruo CORRUPT( 99*557ea5ddSQu Wenruo "regluar or preallocated extent data item size is invalid", 100*557ea5ddSQu Wenruo leaf, root, slot); 101*557ea5ddSQu Wenruo return -EUCLEAN; 102*557ea5ddSQu Wenruo } 103*557ea5ddSQu Wenruo if (!IS_ALIGNED(btrfs_file_extent_ram_bytes(leaf, fi), sectorsize) || 104*557ea5ddSQu Wenruo !IS_ALIGNED(btrfs_file_extent_disk_bytenr(leaf, fi), sectorsize) || 105*557ea5ddSQu Wenruo !IS_ALIGNED(btrfs_file_extent_disk_num_bytes(leaf, fi), sectorsize) || 106*557ea5ddSQu Wenruo !IS_ALIGNED(btrfs_file_extent_offset(leaf, fi), sectorsize) || 107*557ea5ddSQu Wenruo !IS_ALIGNED(btrfs_file_extent_num_bytes(leaf, fi), sectorsize)) { 108*557ea5ddSQu Wenruo CORRUPT( 109*557ea5ddSQu Wenruo "regular or preallocated extent data item has unaligned value", 110*557ea5ddSQu Wenruo leaf, root, slot); 111*557ea5ddSQu Wenruo return -EUCLEAN; 112*557ea5ddSQu Wenruo } 113*557ea5ddSQu Wenruo 114*557ea5ddSQu Wenruo return 0; 115*557ea5ddSQu Wenruo } 116*557ea5ddSQu Wenruo 117*557ea5ddSQu Wenruo static int check_csum_item(struct btrfs_root *root, struct extent_buffer *leaf, 118*557ea5ddSQu Wenruo struct btrfs_key *key, int slot) 119*557ea5ddSQu Wenruo { 120*557ea5ddSQu Wenruo u32 sectorsize = root->fs_info->sectorsize; 121*557ea5ddSQu Wenruo u32 csumsize = btrfs_super_csum_size(root->fs_info->super_copy); 122*557ea5ddSQu Wenruo 123*557ea5ddSQu Wenruo if (key->objectid != BTRFS_EXTENT_CSUM_OBJECTID) { 124*557ea5ddSQu Wenruo CORRUPT("invalid objectid for csum item", leaf, root, slot); 125*557ea5ddSQu Wenruo return -EUCLEAN; 126*557ea5ddSQu Wenruo } 127*557ea5ddSQu Wenruo if (!IS_ALIGNED(key->offset, sectorsize)) { 128*557ea5ddSQu Wenruo CORRUPT("unaligned key offset for csum item", leaf, root, slot); 129*557ea5ddSQu Wenruo return -EUCLEAN; 130*557ea5ddSQu Wenruo } 131*557ea5ddSQu Wenruo if (!IS_ALIGNED(btrfs_item_size_nr(leaf, slot), csumsize)) { 132*557ea5ddSQu Wenruo CORRUPT("unaligned csum item size", leaf, root, slot); 133*557ea5ddSQu Wenruo return -EUCLEAN; 134*557ea5ddSQu Wenruo } 135*557ea5ddSQu Wenruo return 0; 136*557ea5ddSQu Wenruo } 137*557ea5ddSQu Wenruo 138*557ea5ddSQu Wenruo /* 139*557ea5ddSQu Wenruo * Common point to switch the item-specific validation. 140*557ea5ddSQu Wenruo */ 141*557ea5ddSQu Wenruo static int check_leaf_item(struct btrfs_root *root, 142*557ea5ddSQu Wenruo struct extent_buffer *leaf, 143*557ea5ddSQu Wenruo struct btrfs_key *key, int slot) 144*557ea5ddSQu Wenruo { 145*557ea5ddSQu Wenruo int ret = 0; 146*557ea5ddSQu Wenruo 147*557ea5ddSQu Wenruo switch (key->type) { 148*557ea5ddSQu Wenruo case BTRFS_EXTENT_DATA_KEY: 149*557ea5ddSQu Wenruo ret = check_extent_data_item(root, leaf, key, slot); 150*557ea5ddSQu Wenruo break; 151*557ea5ddSQu Wenruo case BTRFS_EXTENT_CSUM_KEY: 152*557ea5ddSQu Wenruo ret = check_csum_item(root, leaf, key, slot); 153*557ea5ddSQu Wenruo break; 154*557ea5ddSQu Wenruo } 155*557ea5ddSQu Wenruo return ret; 156*557ea5ddSQu Wenruo } 157*557ea5ddSQu Wenruo 158*557ea5ddSQu Wenruo int btrfs_check_leaf(struct btrfs_root *root, struct extent_buffer *leaf) 159*557ea5ddSQu Wenruo { 160*557ea5ddSQu Wenruo struct btrfs_fs_info *fs_info = root->fs_info; 161*557ea5ddSQu Wenruo /* No valid key type is 0, so all key should be larger than this key */ 162*557ea5ddSQu Wenruo struct btrfs_key prev_key = {0, 0, 0}; 163*557ea5ddSQu Wenruo struct btrfs_key key; 164*557ea5ddSQu Wenruo u32 nritems = btrfs_header_nritems(leaf); 165*557ea5ddSQu Wenruo int slot; 166*557ea5ddSQu Wenruo 167*557ea5ddSQu Wenruo /* 168*557ea5ddSQu Wenruo * Extent buffers from a relocation tree have a owner field that 169*557ea5ddSQu Wenruo * corresponds to the subvolume tree they are based on. So just from an 170*557ea5ddSQu Wenruo * extent buffer alone we can not find out what is the id of the 171*557ea5ddSQu Wenruo * corresponding subvolume tree, so we can not figure out if the extent 172*557ea5ddSQu Wenruo * buffer corresponds to the root of the relocation tree or not. So 173*557ea5ddSQu Wenruo * skip this check for relocation trees. 174*557ea5ddSQu Wenruo */ 175*557ea5ddSQu Wenruo if (nritems == 0 && !btrfs_header_flag(leaf, BTRFS_HEADER_FLAG_RELOC)) { 176*557ea5ddSQu Wenruo struct btrfs_root *check_root; 177*557ea5ddSQu Wenruo 178*557ea5ddSQu Wenruo key.objectid = btrfs_header_owner(leaf); 179*557ea5ddSQu Wenruo key.type = BTRFS_ROOT_ITEM_KEY; 180*557ea5ddSQu Wenruo key.offset = (u64)-1; 181*557ea5ddSQu Wenruo 182*557ea5ddSQu Wenruo check_root = btrfs_get_fs_root(fs_info, &key, false); 183*557ea5ddSQu Wenruo /* 184*557ea5ddSQu Wenruo * The only reason we also check NULL here is that during 185*557ea5ddSQu Wenruo * open_ctree() some roots has not yet been set up. 186*557ea5ddSQu Wenruo */ 187*557ea5ddSQu Wenruo if (!IS_ERR_OR_NULL(check_root)) { 188*557ea5ddSQu Wenruo struct extent_buffer *eb; 189*557ea5ddSQu Wenruo 190*557ea5ddSQu Wenruo eb = btrfs_root_node(check_root); 191*557ea5ddSQu Wenruo /* if leaf is the root, then it's fine */ 192*557ea5ddSQu Wenruo if (leaf != eb) { 193*557ea5ddSQu Wenruo CORRUPT("non-root leaf's nritems is 0", 194*557ea5ddSQu Wenruo leaf, check_root, 0); 195*557ea5ddSQu Wenruo free_extent_buffer(eb); 196*557ea5ddSQu Wenruo return -EUCLEAN; 197*557ea5ddSQu Wenruo } 198*557ea5ddSQu Wenruo free_extent_buffer(eb); 199*557ea5ddSQu Wenruo } 200*557ea5ddSQu Wenruo return 0; 201*557ea5ddSQu Wenruo } 202*557ea5ddSQu Wenruo 203*557ea5ddSQu Wenruo if (nritems == 0) 204*557ea5ddSQu Wenruo return 0; 205*557ea5ddSQu Wenruo 206*557ea5ddSQu Wenruo /* 207*557ea5ddSQu Wenruo * Check the following things to make sure this is a good leaf, and 208*557ea5ddSQu Wenruo * leaf users won't need to bother with similar sanity checks: 209*557ea5ddSQu Wenruo * 210*557ea5ddSQu Wenruo * 1) key ordering 211*557ea5ddSQu Wenruo * 2) item offset and size 212*557ea5ddSQu Wenruo * No overlap, no hole, all inside the leaf. 213*557ea5ddSQu Wenruo * 3) item content 214*557ea5ddSQu Wenruo * If possible, do comprehensive sanity check. 215*557ea5ddSQu Wenruo * NOTE: All checks must only rely on the item data itself. 216*557ea5ddSQu Wenruo */ 217*557ea5ddSQu Wenruo for (slot = 0; slot < nritems; slot++) { 218*557ea5ddSQu Wenruo u32 item_end_expected; 219*557ea5ddSQu Wenruo int ret; 220*557ea5ddSQu Wenruo 221*557ea5ddSQu Wenruo btrfs_item_key_to_cpu(leaf, &key, slot); 222*557ea5ddSQu Wenruo 223*557ea5ddSQu Wenruo /* Make sure the keys are in the right order */ 224*557ea5ddSQu Wenruo if (btrfs_comp_cpu_keys(&prev_key, &key) >= 0) { 225*557ea5ddSQu Wenruo CORRUPT("bad key order", leaf, root, slot); 226*557ea5ddSQu Wenruo return -EUCLEAN; 227*557ea5ddSQu Wenruo } 228*557ea5ddSQu Wenruo 229*557ea5ddSQu Wenruo /* 230*557ea5ddSQu Wenruo * Make sure the offset and ends are right, remember that the 231*557ea5ddSQu Wenruo * item data starts at the end of the leaf and grows towards the 232*557ea5ddSQu Wenruo * front. 233*557ea5ddSQu Wenruo */ 234*557ea5ddSQu Wenruo if (slot == 0) 235*557ea5ddSQu Wenruo item_end_expected = BTRFS_LEAF_DATA_SIZE(fs_info); 236*557ea5ddSQu Wenruo else 237*557ea5ddSQu Wenruo item_end_expected = btrfs_item_offset_nr(leaf, 238*557ea5ddSQu Wenruo slot - 1); 239*557ea5ddSQu Wenruo if (btrfs_item_end_nr(leaf, slot) != item_end_expected) { 240*557ea5ddSQu Wenruo CORRUPT("slot offset bad", leaf, root, slot); 241*557ea5ddSQu Wenruo return -EUCLEAN; 242*557ea5ddSQu Wenruo } 243*557ea5ddSQu Wenruo 244*557ea5ddSQu Wenruo /* 245*557ea5ddSQu Wenruo * Check to make sure that we don't point outside of the leaf, 246*557ea5ddSQu Wenruo * just in case all the items are consistent to each other, but 247*557ea5ddSQu Wenruo * all point outside of the leaf. 248*557ea5ddSQu Wenruo */ 249*557ea5ddSQu Wenruo if (btrfs_item_end_nr(leaf, slot) > 250*557ea5ddSQu Wenruo BTRFS_LEAF_DATA_SIZE(fs_info)) { 251*557ea5ddSQu Wenruo CORRUPT("slot end outside of leaf", leaf, root, slot); 252*557ea5ddSQu Wenruo return -EUCLEAN; 253*557ea5ddSQu Wenruo } 254*557ea5ddSQu Wenruo 255*557ea5ddSQu Wenruo /* Also check if the item pointer overlaps with btrfs item. */ 256*557ea5ddSQu Wenruo if (btrfs_item_nr_offset(slot) + sizeof(struct btrfs_item) > 257*557ea5ddSQu Wenruo btrfs_item_ptr_offset(leaf, slot)) { 258*557ea5ddSQu Wenruo CORRUPT("slot overlap with its data", leaf, root, slot); 259*557ea5ddSQu Wenruo return -EUCLEAN; 260*557ea5ddSQu Wenruo } 261*557ea5ddSQu Wenruo 262*557ea5ddSQu Wenruo /* Check if the item size and content meet other criteria */ 263*557ea5ddSQu Wenruo ret = check_leaf_item(root, leaf, &key, slot); 264*557ea5ddSQu Wenruo if (ret < 0) 265*557ea5ddSQu Wenruo return ret; 266*557ea5ddSQu Wenruo 267*557ea5ddSQu Wenruo prev_key.objectid = key.objectid; 268*557ea5ddSQu Wenruo prev_key.type = key.type; 269*557ea5ddSQu Wenruo prev_key.offset = key.offset; 270*557ea5ddSQu Wenruo } 271*557ea5ddSQu Wenruo 272*557ea5ddSQu Wenruo return 0; 273*557ea5ddSQu Wenruo } 274*557ea5ddSQu Wenruo 275*557ea5ddSQu Wenruo int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node) 276*557ea5ddSQu Wenruo { 277*557ea5ddSQu Wenruo unsigned long nr = btrfs_header_nritems(node); 278*557ea5ddSQu Wenruo struct btrfs_key key, next_key; 279*557ea5ddSQu Wenruo int slot; 280*557ea5ddSQu Wenruo u64 bytenr; 281*557ea5ddSQu Wenruo int ret = 0; 282*557ea5ddSQu Wenruo 283*557ea5ddSQu Wenruo if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(root->fs_info)) { 284*557ea5ddSQu Wenruo btrfs_crit(root->fs_info, 285*557ea5ddSQu Wenruo "corrupt node: block %llu root %llu nritems %lu", 286*557ea5ddSQu Wenruo node->start, root->objectid, nr); 287*557ea5ddSQu Wenruo return -EIO; 288*557ea5ddSQu Wenruo } 289*557ea5ddSQu Wenruo 290*557ea5ddSQu Wenruo for (slot = 0; slot < nr - 1; slot++) { 291*557ea5ddSQu Wenruo bytenr = btrfs_node_blockptr(node, slot); 292*557ea5ddSQu Wenruo btrfs_node_key_to_cpu(node, &key, slot); 293*557ea5ddSQu Wenruo btrfs_node_key_to_cpu(node, &next_key, slot + 1); 294*557ea5ddSQu Wenruo 295*557ea5ddSQu Wenruo if (!bytenr) { 296*557ea5ddSQu Wenruo CORRUPT("invalid item slot", node, root, slot); 297*557ea5ddSQu Wenruo ret = -EIO; 298*557ea5ddSQu Wenruo goto out; 299*557ea5ddSQu Wenruo } 300*557ea5ddSQu Wenruo 301*557ea5ddSQu Wenruo if (btrfs_comp_cpu_keys(&key, &next_key) >= 0) { 302*557ea5ddSQu Wenruo CORRUPT("bad key order", node, root, slot); 303*557ea5ddSQu Wenruo ret = -EIO; 304*557ea5ddSQu Wenruo goto out; 305*557ea5ddSQu Wenruo } 306*557ea5ddSQu Wenruo } 307*557ea5ddSQu Wenruo out: 308*557ea5ddSQu Wenruo return ret; 309*557ea5ddSQu Wenruo } 310