linux/fs/ubifs/master.c
<<
>>
Prefs
   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 */
  24int 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 */
  64static 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 */
  93static 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
 156out:
 157        ubifs_scan_destroy(sleb);
 158        return -EUCLEAN;
 159
 160out_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 */
 174static 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
 318out:
 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 */
 332int 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 */
 437int 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}
 477