root/fs/ubifs/master.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ubifs_compare_master_node
  2. mst_node_check_hash
  3. scan_for_master
  4. validate_master
  5. ubifs_read_master
  6. ubifs_write_master

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * This file is part of UBIFS.
   4  *
   5  * Copyright (C) 2006-2008 Nokia Corporation.
   6  *
   7  * Authors: Artem Bityutskiy (Битюцкий Артём)
   8  *          Adrian Hunter
   9  */
  10 
  11 /* This file implements reading and writing the master node */
  12 
  13 #include "ubifs.h"
  14 
  15 /**
  16  * ubifs_compare_master_node - compare two UBIFS master nodes
  17  * @c: UBIFS file-system description object
  18  * @m1: the first node
  19  * @m2: the second node
  20  *
  21  * This function compares two UBIFS master nodes. Returns 0 if they are equal
  22  * and nonzero if not.
  23  */
  24 int ubifs_compare_master_node(struct ubifs_info *c, void *m1, void *m2)
  25 {
  26         int ret;
  27         int behind;
  28         int hmac_offs = offsetof(struct ubifs_mst_node, hmac);
  29 
  30         /*
  31          * Do not compare the common node header since the sequence number and
  32          * hence the CRC are different.
  33          */
  34         ret = memcmp(m1 + UBIFS_CH_SZ, m2 + UBIFS_CH_SZ,
  35                      hmac_offs - UBIFS_CH_SZ);
  36         if (ret)
  37                 return ret;
  38 
  39         /*
  40          * Do not compare the embedded HMAC aswell which also must be different
  41          * due to the different common node header.
  42          */
  43         behind = hmac_offs + UBIFS_MAX_HMAC_LEN;
  44 
  45         if (UBIFS_MST_NODE_SZ > behind)
  46                 return memcmp(m1 + behind, m2 + behind, UBIFS_MST_NODE_SZ - behind);
  47 
  48         return 0;
  49 }
  50 
  51 /* mst_node_check_hash - Check hash of a master node
  52  * @c: UBIFS file-system description object
  53  * @mst: The master node
  54  * @expected: The expected hash of the master node
  55  *
  56  * This checks the hash of a master node against a given expected hash.
  57  * Note that we have two master nodes on a UBIFS image which have different
  58  * sequence numbers and consequently different CRCs. To be able to match
  59  * both master nodes we exclude the common node header containing the sequence
  60  * number and CRC from the hash.
  61  *
  62  * Returns 0 if the hashes are equal, a negative error code otherwise.
  63  */
  64 static int mst_node_check_hash(const struct ubifs_info *c,
  65                                const struct ubifs_mst_node *mst,
  66                                const u8 *expected)
  67 {
  68         u8 calc[UBIFS_MAX_HASH_LEN];
  69         const void *node = mst;
  70 
  71         SHASH_DESC_ON_STACK(shash, c->hash_tfm);
  72 
  73         shash->tfm = c->hash_tfm;
  74 
  75         crypto_shash_digest(shash, node + sizeof(struct ubifs_ch),
  76                             UBIFS_MST_NODE_SZ - sizeof(struct ubifs_ch), calc);
  77 
  78         if (ubifs_check_hash(c, expected, calc))
  79                 return -EPERM;
  80 
  81         return 0;
  82 }
  83 
  84 /**
  85  * scan_for_master - search the valid master node.
  86  * @c: UBIFS file-system description object
  87  *
  88  * This function scans the master node LEBs and search for the latest master
  89  * node. Returns zero in case of success, %-EUCLEAN if there master area is
  90  * corrupted and requires recovery, and a negative error code in case of
  91  * failure.
  92  */
  93 static int scan_for_master(struct ubifs_info *c)
  94 {
  95         struct ubifs_scan_leb *sleb;
  96         struct ubifs_scan_node *snod;
  97         int lnum, offs = 0, nodes_cnt, err;
  98 
  99         lnum = UBIFS_MST_LNUM;
 100 
 101         sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1);
 102         if (IS_ERR(sleb))
 103                 return PTR_ERR(sleb);
 104         nodes_cnt = sleb->nodes_cnt;
 105         if (nodes_cnt > 0) {
 106                 snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node,
 107                                   list);
 108                 if (snod->type != UBIFS_MST_NODE)
 109                         goto out_dump;
 110                 memcpy(c->mst_node, snod->node, snod->len);
 111                 offs = snod->offs;
 112         }
 113         ubifs_scan_destroy(sleb);
 114 
 115         lnum += 1;
 116 
 117         sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1);
 118         if (IS_ERR(sleb))
 119                 return PTR_ERR(sleb);
 120         if (sleb->nodes_cnt != nodes_cnt)
 121                 goto out;
 122         if (!sleb->nodes_cnt)
 123                 goto out;
 124         snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, list);
 125         if (snod->type != UBIFS_MST_NODE)
 126                 goto out_dump;
 127         if (snod->offs != offs)
 128                 goto out;
 129         if (ubifs_compare_master_node(c, c->mst_node, snod->node))
 130                 goto out;
 131 
 132         c->mst_offs = offs;
 133         ubifs_scan_destroy(sleb);
 134 
 135         if (!ubifs_authenticated(c))
 136                 return 0;
 137 
 138         if (ubifs_hmac_zero(c, c->mst_node->hmac)) {
 139                 err = mst_node_check_hash(c, c->mst_node,
 140                                           c->sup_node->hash_mst);
 141                 if (err)
 142                         ubifs_err(c, "Failed to verify master node hash");
 143         } else {
 144                 err = ubifs_node_verify_hmac(c, c->mst_node,
 145                                         sizeof(struct ubifs_mst_node),
 146                                         offsetof(struct ubifs_mst_node, hmac));
 147                 if (err)
 148                         ubifs_err(c, "Failed to verify master node HMAC");
 149         }
 150 
 151         if (err)
 152                 return -EPERM;
 153 
 154         return 0;
 155 
 156 out:
 157         ubifs_scan_destroy(sleb);
 158         return -EUCLEAN;
 159 
 160 out_dump:
 161         ubifs_err(c, "unexpected node type %d master LEB %d:%d",
 162                   snod->type, lnum, snod->offs);
 163         ubifs_scan_destroy(sleb);
 164         return -EINVAL;
 165 }
 166 
 167 /**
 168  * validate_master - validate master node.
 169  * @c: UBIFS file-system description object
 170  *
 171  * This function validates data which was read from master node. Returns zero
 172  * if the data is all right and %-EINVAL if not.
 173  */
 174 static int validate_master(const struct ubifs_info *c)
 175 {
 176         long long main_sz;
 177         int err;
 178 
 179         if (c->max_sqnum >= SQNUM_WATERMARK) {
 180                 err = 1;
 181                 goto out;
 182         }
 183 
 184         if (c->cmt_no >= c->max_sqnum) {
 185                 err = 2;
 186                 goto out;
 187         }
 188 
 189         if (c->highest_inum >= INUM_WATERMARK) {
 190                 err = 3;
 191                 goto out;
 192         }
 193 
 194         if (c->lhead_lnum < UBIFS_LOG_LNUM ||
 195             c->lhead_lnum >= UBIFS_LOG_LNUM + c->log_lebs ||
 196             c->lhead_offs < 0 || c->lhead_offs >= c->leb_size ||
 197             c->lhead_offs & (c->min_io_size - 1)) {
 198                 err = 4;
 199                 goto out;
 200         }
 201 
 202         if (c->zroot.lnum >= c->leb_cnt || c->zroot.lnum < c->main_first ||
 203             c->zroot.offs >= c->leb_size || c->zroot.offs & 7) {
 204                 err = 5;
 205                 goto out;
 206         }
 207 
 208         if (c->zroot.len < c->ranges[UBIFS_IDX_NODE].min_len ||
 209             c->zroot.len > c->ranges[UBIFS_IDX_NODE].max_len) {
 210                 err = 6;
 211                 goto out;
 212         }
 213 
 214         if (c->gc_lnum >= c->leb_cnt || c->gc_lnum < c->main_first) {
 215                 err = 7;
 216                 goto out;
 217         }
 218 
 219         if (c->ihead_lnum >= c->leb_cnt || c->ihead_lnum < c->main_first ||
 220             c->ihead_offs % c->min_io_size || c->ihead_offs < 0 ||
 221             c->ihead_offs > c->leb_size || c->ihead_offs & 7) {
 222                 err = 8;
 223                 goto out;
 224         }
 225 
 226         main_sz = (long long)c->main_lebs * c->leb_size;
 227         if (c->bi.old_idx_sz & 7 || c->bi.old_idx_sz >= main_sz) {
 228                 err = 9;
 229                 goto out;
 230         }
 231 
 232         if (c->lpt_lnum < c->lpt_first || c->lpt_lnum > c->lpt_last ||
 233             c->lpt_offs < 0 || c->lpt_offs + c->nnode_sz > c->leb_size) {
 234                 err = 10;
 235                 goto out;
 236         }
 237 
 238         if (c->nhead_lnum < c->lpt_first || c->nhead_lnum > c->lpt_last ||
 239             c->nhead_offs < 0 || c->nhead_offs % c->min_io_size ||
 240             c->nhead_offs > c->leb_size) {
 241                 err = 11;
 242                 goto out;
 243         }
 244 
 245         if (c->ltab_lnum < c->lpt_first || c->ltab_lnum > c->lpt_last ||
 246             c->ltab_offs < 0 ||
 247             c->ltab_offs + c->ltab_sz > c->leb_size) {
 248                 err = 12;
 249                 goto out;
 250         }
 251 
 252         if (c->big_lpt && (c->lsave_lnum < c->lpt_first ||
 253             c->lsave_lnum > c->lpt_last || c->lsave_offs < 0 ||
 254             c->lsave_offs + c->lsave_sz > c->leb_size)) {
 255                 err = 13;
 256                 goto out;
 257         }
 258 
 259         if (c->lscan_lnum < c->main_first || c->lscan_lnum >= c->leb_cnt) {
 260                 err = 14;
 261                 goto out;
 262         }
 263 
 264         if (c->lst.empty_lebs < 0 || c->lst.empty_lebs > c->main_lebs - 2) {
 265                 err = 15;
 266                 goto out;
 267         }
 268 
 269         if (c->lst.idx_lebs < 0 || c->lst.idx_lebs > c->main_lebs - 1) {
 270                 err = 16;
 271                 goto out;
 272         }
 273 
 274         if (c->lst.total_free < 0 || c->lst.total_free > main_sz ||
 275             c->lst.total_free & 7) {
 276                 err = 17;
 277                 goto out;
 278         }
 279 
 280         if (c->lst.total_dirty < 0 || (c->lst.total_dirty & 7)) {
 281                 err = 18;
 282                 goto out;
 283         }
 284 
 285         if (c->lst.total_used < 0 || (c->lst.total_used & 7)) {
 286                 err = 19;
 287                 goto out;
 288         }
 289 
 290         if (c->lst.total_free + c->lst.total_dirty +
 291             c->lst.total_used > main_sz) {
 292                 err = 20;
 293                 goto out;
 294         }
 295 
 296         if (c->lst.total_dead + c->lst.total_dark +
 297             c->lst.total_used + c->bi.old_idx_sz > main_sz) {
 298                 err = 21;
 299                 goto out;
 300         }
 301 
 302         if (c->lst.total_dead < 0 ||
 303             c->lst.total_dead > c->lst.total_free + c->lst.total_dirty ||
 304             c->lst.total_dead & 7) {
 305                 err = 22;
 306                 goto out;
 307         }
 308 
 309         if (c->lst.total_dark < 0 ||
 310             c->lst.total_dark > c->lst.total_free + c->lst.total_dirty ||
 311             c->lst.total_dark & 7) {
 312                 err = 23;
 313                 goto out;
 314         }
 315 
 316         return 0;
 317 
 318 out:
 319         ubifs_err(c, "bad master node at offset %d error %d", c->mst_offs, err);
 320         ubifs_dump_node(c, c->mst_node);
 321         return -EINVAL;
 322 }
 323 
 324 /**
 325  * ubifs_read_master - read master node.
 326  * @c: UBIFS file-system description object
 327  *
 328  * This function finds and reads the master node during file-system mount. If
 329  * the flash is empty, it creates default master node as well. Returns zero in
 330  * case of success and a negative error code in case of failure.
 331  */
 332 int ubifs_read_master(struct ubifs_info *c)
 333 {
 334         int err, old_leb_cnt;
 335 
 336         c->mst_node = kzalloc(c->mst_node_alsz, GFP_KERNEL);
 337         if (!c->mst_node)
 338                 return -ENOMEM;
 339 
 340         err = scan_for_master(c);
 341         if (err) {
 342                 if (err == -EUCLEAN)
 343                         err = ubifs_recover_master_node(c);
 344                 if (err)
 345                         /*
 346                          * Note, we do not free 'c->mst_node' here because the
 347                          * unmount routine will take care of this.
 348                          */
 349                         return err;
 350         }
 351 
 352         /* Make sure that the recovery flag is clear */
 353         c->mst_node->flags &= cpu_to_le32(~UBIFS_MST_RCVRY);
 354 
 355         c->max_sqnum       = le64_to_cpu(c->mst_node->ch.sqnum);
 356         c->highest_inum    = le64_to_cpu(c->mst_node->highest_inum);
 357         c->cmt_no          = le64_to_cpu(c->mst_node->cmt_no);
 358         c->zroot.lnum      = le32_to_cpu(c->mst_node->root_lnum);
 359         c->zroot.offs      = le32_to_cpu(c->mst_node->root_offs);
 360         c->zroot.len       = le32_to_cpu(c->mst_node->root_len);
 361         c->lhead_lnum      = le32_to_cpu(c->mst_node->log_lnum);
 362         c->gc_lnum         = le32_to_cpu(c->mst_node->gc_lnum);
 363         c->ihead_lnum      = le32_to_cpu(c->mst_node->ihead_lnum);
 364         c->ihead_offs      = le32_to_cpu(c->mst_node->ihead_offs);
 365         c->bi.old_idx_sz   = le64_to_cpu(c->mst_node->index_size);
 366         c->lpt_lnum        = le32_to_cpu(c->mst_node->lpt_lnum);
 367         c->lpt_offs        = le32_to_cpu(c->mst_node->lpt_offs);
 368         c->nhead_lnum      = le32_to_cpu(c->mst_node->nhead_lnum);
 369         c->nhead_offs      = le32_to_cpu(c->mst_node->nhead_offs);
 370         c->ltab_lnum       = le32_to_cpu(c->mst_node->ltab_lnum);
 371         c->ltab_offs       = le32_to_cpu(c->mst_node->ltab_offs);
 372         c->lsave_lnum      = le32_to_cpu(c->mst_node->lsave_lnum);
 373         c->lsave_offs      = le32_to_cpu(c->mst_node->lsave_offs);
 374         c->lscan_lnum      = le32_to_cpu(c->mst_node->lscan_lnum);
 375         c->lst.empty_lebs  = le32_to_cpu(c->mst_node->empty_lebs);
 376         c->lst.idx_lebs    = le32_to_cpu(c->mst_node->idx_lebs);
 377         old_leb_cnt        = le32_to_cpu(c->mst_node->leb_cnt);
 378         c->lst.total_free  = le64_to_cpu(c->mst_node->total_free);
 379         c->lst.total_dirty = le64_to_cpu(c->mst_node->total_dirty);
 380         c->lst.total_used  = le64_to_cpu(c->mst_node->total_used);
 381         c->lst.total_dead  = le64_to_cpu(c->mst_node->total_dead);
 382         c->lst.total_dark  = le64_to_cpu(c->mst_node->total_dark);
 383 
 384         ubifs_copy_hash(c, c->mst_node->hash_root_idx, c->zroot.hash);
 385 
 386         c->calc_idx_sz = c->bi.old_idx_sz;
 387 
 388         if (c->mst_node->flags & cpu_to_le32(UBIFS_MST_NO_ORPHS))
 389                 c->no_orphs = 1;
 390 
 391         if (old_leb_cnt != c->leb_cnt) {
 392                 /* The file system has been resized */
 393                 int growth = c->leb_cnt - old_leb_cnt;
 394 
 395                 if (c->leb_cnt < old_leb_cnt ||
 396                     c->leb_cnt < UBIFS_MIN_LEB_CNT) {
 397                         ubifs_err(c, "bad leb_cnt on master node");
 398                         ubifs_dump_node(c, c->mst_node);
 399                         return -EINVAL;
 400                 }
 401 
 402                 dbg_mnt("Auto resizing (master) from %d LEBs to %d LEBs",
 403                         old_leb_cnt, c->leb_cnt);
 404                 c->lst.empty_lebs += growth;
 405                 c->lst.total_free += growth * (long long)c->leb_size;
 406                 c->lst.total_dark += growth * (long long)c->dark_wm;
 407 
 408                 /*
 409                  * Reflect changes back onto the master node. N.B. the master
 410                  * node gets written immediately whenever mounting (or
 411                  * remounting) in read-write mode, so we do not need to write it
 412                  * here.
 413                  */
 414                 c->mst_node->leb_cnt = cpu_to_le32(c->leb_cnt);
 415                 c->mst_node->empty_lebs = cpu_to_le32(c->lst.empty_lebs);
 416                 c->mst_node->total_free = cpu_to_le64(c->lst.total_free);
 417                 c->mst_node->total_dark = cpu_to_le64(c->lst.total_dark);
 418         }
 419 
 420         err = validate_master(c);
 421         if (err)
 422                 return err;
 423 
 424         err = dbg_old_index_check_init(c, &c->zroot);
 425 
 426         return err;
 427 }
 428 
 429 /**
 430  * ubifs_write_master - write master node.
 431  * @c: UBIFS file-system description object
 432  *
 433  * This function writes the master node. Returns zero in case of success and a
 434  * negative error code in case of failure. The master node is written twice to
 435  * enable recovery.
 436  */
 437 int ubifs_write_master(struct ubifs_info *c)
 438 {
 439         int err, lnum, offs, len;
 440 
 441         ubifs_assert(c, !c->ro_media && !c->ro_mount);
 442         if (c->ro_error)
 443                 return -EROFS;
 444 
 445         lnum = UBIFS_MST_LNUM;
 446         offs = c->mst_offs + c->mst_node_alsz;
 447         len = UBIFS_MST_NODE_SZ;
 448 
 449         if (offs + UBIFS_MST_NODE_SZ > c->leb_size) {
 450                 err = ubifs_leb_unmap(c, lnum);
 451                 if (err)
 452                         return err;
 453                 offs = 0;
 454         }
 455 
 456         c->mst_offs = offs;
 457         c->mst_node->highest_inum = cpu_to_le64(c->highest_inum);
 458 
 459         ubifs_copy_hash(c, c->zroot.hash, c->mst_node->hash_root_idx);
 460         err = ubifs_write_node_hmac(c, c->mst_node, len, lnum, offs,
 461                                     offsetof(struct ubifs_mst_node, hmac));
 462         if (err)
 463                 return err;
 464 
 465         lnum += 1;
 466 
 467         if (offs == 0) {
 468                 err = ubifs_leb_unmap(c, lnum);
 469                 if (err)
 470                         return err;
 471         }
 472         err = ubifs_write_node_hmac(c, c->mst_node, len, lnum, offs,
 473                                     offsetof(struct ubifs_mst_node, hmac));
 474 
 475         return err;
 476 }

/* [<][>][^][v][top][bottom][index][help] */