| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * This file is part of UBIFS. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2006-2008 Nokia Corporation. |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms of the GNU General Public License version 2 as published by |
|---|
| 8 | | - * the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 13 | | - * more details. |
|---|
| 14 | | - * |
|---|
| 15 | | - * You should have received a copy of the GNU General Public License along with |
|---|
| 16 | | - * this program; if not, write to the Free Software Foundation, Inc., 51 |
|---|
| 17 | | - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|---|
| 18 | 6 | * |
|---|
| 19 | 7 | * Authors: Artem Bityutskiy (Битюцкий Артём) |
|---|
| 20 | 8 | * Adrian Hunter |
|---|
| .. | .. |
|---|
| 93 | 81 | int err, tmp, jnl_lebs, log_lebs, max_buds, main_lebs, main_first; |
|---|
| 94 | 82 | int lpt_lebs, lpt_first, orph_lebs, big_lpt, ino_waste, sup_flags = 0; |
|---|
| 95 | 83 | int min_leb_cnt = UBIFS_MIN_LEB_CNT; |
|---|
| 84 | + int idx_node_size; |
|---|
| 96 | 85 | long long tmp64, main_bytes; |
|---|
| 97 | 86 | __le64 tmp_le64; |
|---|
| 98 | | - __le32 tmp_le32; |
|---|
| 99 | 87 | struct timespec64 ts; |
|---|
| 88 | + u8 hash[UBIFS_HASH_ARR_SZ]; |
|---|
| 89 | + u8 hash_lpt[UBIFS_HASH_ARR_SZ]; |
|---|
| 100 | 90 | |
|---|
| 101 | 91 | /* Some functions called from here depend on the @c->key_len filed */ |
|---|
| 102 | 92 | c->key_len = UBIFS_SK_LEN; |
|---|
| .. | .. |
|---|
| 158 | 148 | c->lsave_cnt = DEFAULT_LSAVE_CNT; |
|---|
| 159 | 149 | c->max_leb_cnt = c->leb_cnt; |
|---|
| 160 | 150 | err = ubifs_create_dflt_lpt(c, &main_lebs, lpt_first, &lpt_lebs, |
|---|
| 161 | | - &big_lpt); |
|---|
| 151 | + &big_lpt, hash_lpt); |
|---|
| 162 | 152 | if (err) |
|---|
| 163 | 153 | return err; |
|---|
| 164 | 154 | |
|---|
| .. | .. |
|---|
| 167 | 157 | |
|---|
| 168 | 158 | main_first = c->leb_cnt - main_lebs; |
|---|
| 169 | 159 | |
|---|
| 160 | + sup = kzalloc(ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size), GFP_KERNEL); |
|---|
| 161 | + mst = kzalloc(c->mst_node_alsz, GFP_KERNEL); |
|---|
| 162 | + idx_node_size = ubifs_idx_node_sz(c, 1); |
|---|
| 163 | + idx = kzalloc(ALIGN(idx_node_size, c->min_io_size), GFP_KERNEL); |
|---|
| 164 | + ino = kzalloc(ALIGN(UBIFS_INO_NODE_SZ, c->min_io_size), GFP_KERNEL); |
|---|
| 165 | + cs = kzalloc(ALIGN(UBIFS_CS_NODE_SZ, c->min_io_size), GFP_KERNEL); |
|---|
| 166 | + |
|---|
| 167 | + if (!sup || !mst || !idx || !ino || !cs) { |
|---|
| 168 | + err = -ENOMEM; |
|---|
| 169 | + goto out; |
|---|
| 170 | + } |
|---|
| 171 | + |
|---|
| 170 | 172 | /* Create default superblock */ |
|---|
| 171 | | - tmp = ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size); |
|---|
| 172 | | - sup = kzalloc(tmp, GFP_KERNEL); |
|---|
| 173 | | - if (!sup) |
|---|
| 174 | | - return -ENOMEM; |
|---|
| 175 | 173 | |
|---|
| 176 | 174 | tmp64 = (long long)max_buds * c->leb_size; |
|---|
| 177 | 175 | if (big_lpt) |
|---|
| 178 | 176 | sup_flags |= UBIFS_FLG_BIGLPT; |
|---|
| 179 | | - sup_flags |= UBIFS_FLG_DOUBLE_HASH; |
|---|
| 177 | + if (ubifs_default_version > 4) |
|---|
| 178 | + sup_flags |= UBIFS_FLG_DOUBLE_HASH; |
|---|
| 179 | + |
|---|
| 180 | + if (ubifs_authenticated(c)) { |
|---|
| 181 | + sup_flags |= UBIFS_FLG_AUTHENTICATION; |
|---|
| 182 | + sup->hash_algo = cpu_to_le16(c->auth_hash_algo); |
|---|
| 183 | + err = ubifs_hmac_wkm(c, sup->hmac_wkm); |
|---|
| 184 | + if (err) |
|---|
| 185 | + goto out; |
|---|
| 186 | + } else { |
|---|
| 187 | + sup->hash_algo = cpu_to_le16(0xffff); |
|---|
| 188 | + } |
|---|
| 180 | 189 | |
|---|
| 181 | 190 | sup->ch.node_type = UBIFS_SB_NODE; |
|---|
| 182 | 191 | sup->key_hash = UBIFS_KEY_HASH_R5; |
|---|
| .. | .. |
|---|
| 192 | 201 | sup->jhead_cnt = cpu_to_le32(DEFAULT_JHEADS_CNT); |
|---|
| 193 | 202 | sup->fanout = cpu_to_le32(DEFAULT_FANOUT); |
|---|
| 194 | 203 | sup->lsave_cnt = cpu_to_le32(c->lsave_cnt); |
|---|
| 195 | | - sup->fmt_version = cpu_to_le32(UBIFS_FORMAT_VERSION); |
|---|
| 204 | + sup->fmt_version = cpu_to_le32(ubifs_default_version); |
|---|
| 196 | 205 | sup->time_gran = cpu_to_le32(DEFAULT_TIME_GRAN); |
|---|
| 197 | 206 | if (c->mount_opts.override_compr) |
|---|
| 198 | 207 | sup->default_compr = cpu_to_le16(c->mount_opts.compr_type); |
|---|
| .. | .. |
|---|
| 208 | 217 | sup->rp_size = cpu_to_le64(tmp64); |
|---|
| 209 | 218 | sup->ro_compat_version = cpu_to_le32(UBIFS_RO_COMPAT_VERSION); |
|---|
| 210 | 219 | |
|---|
| 211 | | - err = ubifs_write_node(c, sup, UBIFS_SB_NODE_SZ, 0, 0); |
|---|
| 212 | | - kfree(sup); |
|---|
| 213 | | - if (err) |
|---|
| 214 | | - return err; |
|---|
| 215 | | - |
|---|
| 216 | 220 | dbg_gen("default superblock created at LEB 0:0"); |
|---|
| 217 | 221 | |
|---|
| 218 | 222 | /* Create default master node */ |
|---|
| 219 | | - mst = kzalloc(c->mst_node_alsz, GFP_KERNEL); |
|---|
| 220 | | - if (!mst) |
|---|
| 221 | | - return -ENOMEM; |
|---|
| 222 | 223 | |
|---|
| 223 | 224 | mst->ch.node_type = UBIFS_MST_NODE; |
|---|
| 224 | 225 | mst->log_lnum = cpu_to_le32(UBIFS_LOG_LNUM); |
|---|
| .. | .. |
|---|
| 244 | 245 | mst->empty_lebs = cpu_to_le32(main_lebs - 2); |
|---|
| 245 | 246 | mst->idx_lebs = cpu_to_le32(1); |
|---|
| 246 | 247 | mst->leb_cnt = cpu_to_le32(c->leb_cnt); |
|---|
| 248 | + ubifs_copy_hash(c, hash_lpt, mst->hash_lpt); |
|---|
| 247 | 249 | |
|---|
| 248 | 250 | /* Calculate lprops statistics */ |
|---|
| 249 | 251 | tmp64 = main_bytes; |
|---|
| .. | .. |
|---|
| 264 | 266 | |
|---|
| 265 | 267 | mst->total_used = cpu_to_le64(UBIFS_INO_NODE_SZ); |
|---|
| 266 | 268 | |
|---|
| 267 | | - err = ubifs_write_node(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM, 0); |
|---|
| 268 | | - if (err) { |
|---|
| 269 | | - kfree(mst); |
|---|
| 270 | | - return err; |
|---|
| 271 | | - } |
|---|
| 272 | | - err = ubifs_write_node(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM + 1, |
|---|
| 273 | | - 0); |
|---|
| 274 | | - kfree(mst); |
|---|
| 275 | | - if (err) |
|---|
| 276 | | - return err; |
|---|
| 277 | | - |
|---|
| 278 | 269 | dbg_gen("default master node created at LEB %d:0", UBIFS_MST_LNUM); |
|---|
| 279 | 270 | |
|---|
| 280 | 271 | /* Create the root indexing node */ |
|---|
| 281 | | - tmp = ubifs_idx_node_sz(c, 1); |
|---|
| 282 | | - idx = kzalloc(ALIGN(tmp, c->min_io_size), GFP_KERNEL); |
|---|
| 283 | | - if (!idx) |
|---|
| 284 | | - return -ENOMEM; |
|---|
| 285 | 272 | |
|---|
| 286 | 273 | c->key_fmt = UBIFS_SIMPLE_KEY_FMT; |
|---|
| 287 | 274 | c->key_hash = key_r5_hash; |
|---|
| .. | .. |
|---|
| 293 | 280 | key_write_idx(c, &key, &br->key); |
|---|
| 294 | 281 | br->lnum = cpu_to_le32(main_first + DEFAULT_DATA_LEB); |
|---|
| 295 | 282 | br->len = cpu_to_le32(UBIFS_INO_NODE_SZ); |
|---|
| 296 | | - err = ubifs_write_node(c, idx, tmp, main_first + DEFAULT_IDX_LEB, 0); |
|---|
| 297 | | - kfree(idx); |
|---|
| 298 | | - if (err) |
|---|
| 299 | | - return err; |
|---|
| 300 | 283 | |
|---|
| 301 | 284 | dbg_gen("default root indexing node created LEB %d:0", |
|---|
| 302 | 285 | main_first + DEFAULT_IDX_LEB); |
|---|
| 303 | 286 | |
|---|
| 304 | 287 | /* Create default root inode */ |
|---|
| 305 | | - tmp = ALIGN(UBIFS_INO_NODE_SZ, c->min_io_size); |
|---|
| 306 | | - ino = kzalloc(tmp, GFP_KERNEL); |
|---|
| 307 | | - if (!ino) |
|---|
| 308 | | - return -ENOMEM; |
|---|
| 309 | 288 | |
|---|
| 310 | 289 | ino_key_init_flash(c, &ino->key, UBIFS_ROOT_INO); |
|---|
| 311 | 290 | ino->ch.node_type = UBIFS_INO_NODE; |
|---|
| 312 | 291 | ino->creat_sqnum = cpu_to_le64(++c->max_sqnum); |
|---|
| 313 | 292 | ino->nlink = cpu_to_le32(2); |
|---|
| 314 | 293 | |
|---|
| 315 | | - ktime_get_real_ts64(&ts); |
|---|
| 316 | | - ts = timespec64_trunc(ts, DEFAULT_TIME_GRAN); |
|---|
| 294 | + ktime_get_coarse_real_ts64(&ts); |
|---|
| 317 | 295 | tmp_le64 = cpu_to_le64(ts.tv_sec); |
|---|
| 318 | 296 | ino->atime_sec = tmp_le64; |
|---|
| 319 | 297 | ino->ctime_sec = tmp_le64; |
|---|
| 320 | 298 | ino->mtime_sec = tmp_le64; |
|---|
| 321 | | - tmp_le32 = cpu_to_le32(ts.tv_nsec); |
|---|
| 322 | | - ino->atime_nsec = tmp_le32; |
|---|
| 323 | | - ino->ctime_nsec = tmp_le32; |
|---|
| 324 | | - ino->mtime_nsec = tmp_le32; |
|---|
| 299 | + ino->atime_nsec = 0; |
|---|
| 300 | + ino->ctime_nsec = 0; |
|---|
| 301 | + ino->mtime_nsec = 0; |
|---|
| 325 | 302 | ino->mode = cpu_to_le32(S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO); |
|---|
| 326 | 303 | ino->size = cpu_to_le64(UBIFS_INO_NODE_SZ); |
|---|
| 327 | 304 | |
|---|
| 328 | 305 | /* Set compression enabled by default */ |
|---|
| 329 | 306 | ino->flags = cpu_to_le32(UBIFS_COMPR_FL); |
|---|
| 330 | | - |
|---|
| 331 | | - err = ubifs_write_node(c, ino, UBIFS_INO_NODE_SZ, |
|---|
| 332 | | - main_first + DEFAULT_DATA_LEB, 0); |
|---|
| 333 | | - kfree(ino); |
|---|
| 334 | | - if (err) |
|---|
| 335 | | - return err; |
|---|
| 336 | 307 | |
|---|
| 337 | 308 | dbg_gen("root inode created at LEB %d:0", |
|---|
| 338 | 309 | main_first + DEFAULT_DATA_LEB); |
|---|
| .. | .. |
|---|
| 342 | 313 | * always the case during normal file-system operation. Write a fake |
|---|
| 343 | 314 | * commit start node to the log. |
|---|
| 344 | 315 | */ |
|---|
| 345 | | - tmp = ALIGN(UBIFS_CS_NODE_SZ, c->min_io_size); |
|---|
| 346 | | - cs = kzalloc(tmp, GFP_KERNEL); |
|---|
| 347 | | - if (!cs) |
|---|
| 348 | | - return -ENOMEM; |
|---|
| 349 | 316 | |
|---|
| 350 | 317 | cs->ch.node_type = UBIFS_CS_NODE; |
|---|
| 351 | | - err = ubifs_write_node(c, cs, UBIFS_CS_NODE_SZ, UBIFS_LOG_LNUM, 0); |
|---|
| 352 | | - kfree(cs); |
|---|
| 318 | + |
|---|
| 319 | + err = ubifs_write_node_hmac(c, sup, UBIFS_SB_NODE_SZ, 0, 0, |
|---|
| 320 | + offsetof(struct ubifs_sb_node, hmac)); |
|---|
| 353 | 321 | if (err) |
|---|
| 354 | | - return err; |
|---|
| 322 | + goto out; |
|---|
| 323 | + |
|---|
| 324 | + err = ubifs_write_node(c, ino, UBIFS_INO_NODE_SZ, |
|---|
| 325 | + main_first + DEFAULT_DATA_LEB, 0); |
|---|
| 326 | + if (err) |
|---|
| 327 | + goto out; |
|---|
| 328 | + |
|---|
| 329 | + ubifs_node_calc_hash(c, ino, hash); |
|---|
| 330 | + ubifs_copy_hash(c, hash, ubifs_branch_hash(c, br)); |
|---|
| 331 | + |
|---|
| 332 | + err = ubifs_write_node(c, idx, idx_node_size, main_first + DEFAULT_IDX_LEB, 0); |
|---|
| 333 | + if (err) |
|---|
| 334 | + goto out; |
|---|
| 335 | + |
|---|
| 336 | + ubifs_node_calc_hash(c, idx, hash); |
|---|
| 337 | + ubifs_copy_hash(c, hash, mst->hash_root_idx); |
|---|
| 338 | + |
|---|
| 339 | + err = ubifs_write_node_hmac(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM, 0, |
|---|
| 340 | + offsetof(struct ubifs_mst_node, hmac)); |
|---|
| 341 | + if (err) |
|---|
| 342 | + goto out; |
|---|
| 343 | + |
|---|
| 344 | + err = ubifs_write_node_hmac(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM + 1, |
|---|
| 345 | + 0, offsetof(struct ubifs_mst_node, hmac)); |
|---|
| 346 | + if (err) |
|---|
| 347 | + goto out; |
|---|
| 348 | + |
|---|
| 349 | + err = ubifs_write_node(c, cs, UBIFS_CS_NODE_SZ, UBIFS_LOG_LNUM, 0); |
|---|
| 350 | + if (err) |
|---|
| 351 | + goto out; |
|---|
| 355 | 352 | |
|---|
| 356 | 353 | ubifs_msg(c, "default file-system created"); |
|---|
| 357 | | - return 0; |
|---|
| 354 | + |
|---|
| 355 | + err = 0; |
|---|
| 356 | +out: |
|---|
| 357 | + kfree(sup); |
|---|
| 358 | + kfree(mst); |
|---|
| 359 | + kfree(idx); |
|---|
| 360 | + kfree(ino); |
|---|
| 361 | + kfree(cs); |
|---|
| 362 | + |
|---|
| 363 | + return err; |
|---|
| 358 | 364 | } |
|---|
| 359 | 365 | |
|---|
| 360 | 366 | /** |
|---|
| .. | .. |
|---|
| 509 | 515 | * code. Note, the user of this function is responsible of kfree()'ing the |
|---|
| 510 | 516 | * returned superblock buffer. |
|---|
| 511 | 517 | */ |
|---|
| 512 | | -struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c) |
|---|
| 518 | +static struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c) |
|---|
| 513 | 519 | { |
|---|
| 514 | 520 | struct ubifs_sb_node *sup; |
|---|
| 515 | 521 | int err; |
|---|
| .. | .. |
|---|
| 528 | 534 | return sup; |
|---|
| 529 | 535 | } |
|---|
| 530 | 536 | |
|---|
| 537 | +static int authenticate_sb_node(struct ubifs_info *c, |
|---|
| 538 | + const struct ubifs_sb_node *sup) |
|---|
| 539 | +{ |
|---|
| 540 | + unsigned int sup_flags = le32_to_cpu(sup->flags); |
|---|
| 541 | + u8 hmac_wkm[UBIFS_HMAC_ARR_SZ]; |
|---|
| 542 | + int authenticated = !!(sup_flags & UBIFS_FLG_AUTHENTICATION); |
|---|
| 543 | + int hash_algo; |
|---|
| 544 | + int err; |
|---|
| 545 | + |
|---|
| 546 | + if (c->authenticated && !authenticated) { |
|---|
| 547 | + ubifs_err(c, "authenticated FS forced, but found FS without authentication"); |
|---|
| 548 | + return -EINVAL; |
|---|
| 549 | + } |
|---|
| 550 | + |
|---|
| 551 | + if (!c->authenticated && authenticated) { |
|---|
| 552 | + ubifs_err(c, "authenticated FS found, but no key given"); |
|---|
| 553 | + return -EINVAL; |
|---|
| 554 | + } |
|---|
| 555 | + |
|---|
| 556 | + ubifs_msg(c, "Mounting in %sauthenticated mode", |
|---|
| 557 | + c->authenticated ? "" : "un"); |
|---|
| 558 | + |
|---|
| 559 | + if (!c->authenticated) |
|---|
| 560 | + return 0; |
|---|
| 561 | + |
|---|
| 562 | + if (!IS_ENABLED(CONFIG_UBIFS_FS_AUTHENTICATION)) |
|---|
| 563 | + return -EOPNOTSUPP; |
|---|
| 564 | + |
|---|
| 565 | + hash_algo = le16_to_cpu(sup->hash_algo); |
|---|
| 566 | + if (hash_algo >= HASH_ALGO__LAST) { |
|---|
| 567 | + ubifs_err(c, "superblock uses unknown hash algo %d", |
|---|
| 568 | + hash_algo); |
|---|
| 569 | + return -EINVAL; |
|---|
| 570 | + } |
|---|
| 571 | + |
|---|
| 572 | + if (strcmp(hash_algo_name[hash_algo], c->auth_hash_name)) { |
|---|
| 573 | + ubifs_err(c, "This filesystem uses %s for hashing," |
|---|
| 574 | + " but %s is specified", hash_algo_name[hash_algo], |
|---|
| 575 | + c->auth_hash_name); |
|---|
| 576 | + return -EINVAL; |
|---|
| 577 | + } |
|---|
| 578 | + |
|---|
| 579 | + /* |
|---|
| 580 | + * The super block node can either be authenticated by a HMAC or |
|---|
| 581 | + * by a signature in a ubifs_sig_node directly following the |
|---|
| 582 | + * super block node to support offline image creation. |
|---|
| 583 | + */ |
|---|
| 584 | + if (ubifs_hmac_zero(c, sup->hmac)) { |
|---|
| 585 | + err = ubifs_sb_verify_signature(c, sup); |
|---|
| 586 | + } else { |
|---|
| 587 | + err = ubifs_hmac_wkm(c, hmac_wkm); |
|---|
| 588 | + if (err) |
|---|
| 589 | + return err; |
|---|
| 590 | + if (ubifs_check_hmac(c, hmac_wkm, sup->hmac_wkm)) { |
|---|
| 591 | + ubifs_err(c, "provided key does not fit"); |
|---|
| 592 | + return -ENOKEY; |
|---|
| 593 | + } |
|---|
| 594 | + err = ubifs_node_verify_hmac(c, sup, sizeof(*sup), |
|---|
| 595 | + offsetof(struct ubifs_sb_node, |
|---|
| 596 | + hmac)); |
|---|
| 597 | + } |
|---|
| 598 | + |
|---|
| 599 | + if (err) |
|---|
| 600 | + ubifs_err(c, "Failed to authenticate superblock: %d", err); |
|---|
| 601 | + |
|---|
| 602 | + return err; |
|---|
| 603 | +} |
|---|
| 604 | + |
|---|
| 531 | 605 | /** |
|---|
| 532 | 606 | * ubifs_write_sb_node - write superblock node. |
|---|
| 533 | 607 | * @c: UBIFS file-system description object |
|---|
| .. | .. |
|---|
| 538 | 612 | int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup) |
|---|
| 539 | 613 | { |
|---|
| 540 | 614 | int len = ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size); |
|---|
| 615 | + int err; |
|---|
| 541 | 616 | |
|---|
| 542 | | - ubifs_prepare_node(c, sup, UBIFS_SB_NODE_SZ, 1); |
|---|
| 617 | + err = ubifs_prepare_node_hmac(c, sup, UBIFS_SB_NODE_SZ, |
|---|
| 618 | + offsetof(struct ubifs_sb_node, hmac), 1); |
|---|
| 619 | + if (err) |
|---|
| 620 | + return err; |
|---|
| 621 | + |
|---|
| 543 | 622 | return ubifs_leb_change(c, UBIFS_SB_LNUM, sup, len); |
|---|
| 544 | 623 | } |
|---|
| 545 | 624 | |
|---|
| .. | .. |
|---|
| 565 | 644 | sup = ubifs_read_sb_node(c); |
|---|
| 566 | 645 | if (IS_ERR(sup)) |
|---|
| 567 | 646 | return PTR_ERR(sup); |
|---|
| 647 | + |
|---|
| 648 | + c->sup_node = sup; |
|---|
| 568 | 649 | |
|---|
| 569 | 650 | c->fmt_version = le32_to_cpu(sup->fmt_version); |
|---|
| 570 | 651 | c->ro_compat_version = le32_to_cpu(sup->ro_compat_version); |
|---|
| .. | .. |
|---|
| 614 | 695 | c->key_hash = key_test_hash; |
|---|
| 615 | 696 | c->key_hash_type = UBIFS_KEY_HASH_TEST; |
|---|
| 616 | 697 | break; |
|---|
| 617 | | - }; |
|---|
| 698 | + } |
|---|
| 618 | 699 | |
|---|
| 619 | 700 | c->key_fmt = sup->key_fmt; |
|---|
| 620 | 701 | |
|---|
| .. | .. |
|---|
| 651 | 732 | c->double_hash = !!(sup_flags & UBIFS_FLG_DOUBLE_HASH); |
|---|
| 652 | 733 | c->encrypted = !!(sup_flags & UBIFS_FLG_ENCRYPTION); |
|---|
| 653 | 734 | |
|---|
| 735 | + err = authenticate_sb_node(c, sup); |
|---|
| 736 | + if (err) |
|---|
| 737 | + goto out; |
|---|
| 738 | + |
|---|
| 654 | 739 | if ((sup_flags & ~UBIFS_FLG_MASK) != 0) { |
|---|
| 655 | 740 | ubifs_err(c, "Unknown feature flags found: %#x", |
|---|
| 656 | 741 | sup_flags & ~UBIFS_FLG_MASK); |
|---|
| .. | .. |
|---|
| 658 | 743 | goto out; |
|---|
| 659 | 744 | } |
|---|
| 660 | 745 | |
|---|
| 661 | | -#ifndef CONFIG_FS_ENCRYPTION |
|---|
| 662 | | - if (c->encrypted) { |
|---|
| 746 | + if (!IS_ENABLED(CONFIG_FS_ENCRYPTION) && c->encrypted) { |
|---|
| 663 | 747 | ubifs_err(c, "file system contains encrypted files but UBIFS" |
|---|
| 664 | 748 | " was built without crypto support."); |
|---|
| 665 | 749 | err = -EINVAL; |
|---|
| 666 | 750 | goto out; |
|---|
| 667 | 751 | } |
|---|
| 668 | | -#endif |
|---|
| 669 | 752 | |
|---|
| 670 | 753 | /* Automatically increase file system size to the maximum size */ |
|---|
| 671 | | - c->old_leb_cnt = c->leb_cnt; |
|---|
| 672 | 754 | if (c->leb_cnt < c->vi.size && c->leb_cnt < c->max_leb_cnt) { |
|---|
| 755 | + int old_leb_cnt = c->leb_cnt; |
|---|
| 756 | + |
|---|
| 673 | 757 | c->leb_cnt = min_t(int, c->max_leb_cnt, c->vi.size); |
|---|
| 674 | | - if (c->ro_mount) |
|---|
| 675 | | - dbg_mnt("Auto resizing (ro) from %d LEBs to %d LEBs", |
|---|
| 676 | | - c->old_leb_cnt, c->leb_cnt); |
|---|
| 677 | | - else { |
|---|
| 678 | | - dbg_mnt("Auto resizing (sb) from %d LEBs to %d LEBs", |
|---|
| 679 | | - c->old_leb_cnt, c->leb_cnt); |
|---|
| 680 | | - sup->leb_cnt = cpu_to_le32(c->leb_cnt); |
|---|
| 681 | | - err = ubifs_write_sb_node(c, sup); |
|---|
| 682 | | - if (err) |
|---|
| 683 | | - goto out; |
|---|
| 684 | | - c->old_leb_cnt = c->leb_cnt; |
|---|
| 685 | | - } |
|---|
| 758 | + sup->leb_cnt = cpu_to_le32(c->leb_cnt); |
|---|
| 759 | + |
|---|
| 760 | + c->superblock_need_write = 1; |
|---|
| 761 | + |
|---|
| 762 | + dbg_mnt("Auto resizing from %d LEBs to %d LEBs", |
|---|
| 763 | + old_leb_cnt, c->leb_cnt); |
|---|
| 686 | 764 | } |
|---|
| 687 | 765 | |
|---|
| 688 | 766 | c->log_bytes = (long long)c->log_lebs * c->leb_size; |
|---|
| .. | .. |
|---|
| 697 | 775 | |
|---|
| 698 | 776 | err = validate_sb(c, sup); |
|---|
| 699 | 777 | out: |
|---|
| 700 | | - kfree(sup); |
|---|
| 701 | 778 | return err; |
|---|
| 702 | 779 | } |
|---|
| 703 | 780 | |
|---|
| .. | .. |
|---|
| 826 | 903 | int ubifs_fixup_free_space(struct ubifs_info *c) |
|---|
| 827 | 904 | { |
|---|
| 828 | 905 | int err; |
|---|
| 829 | | - struct ubifs_sb_node *sup; |
|---|
| 906 | + struct ubifs_sb_node *sup = c->sup_node; |
|---|
| 830 | 907 | |
|---|
| 831 | 908 | ubifs_assert(c, c->space_fixup); |
|---|
| 832 | 909 | ubifs_assert(c, !c->ro_mount); |
|---|
| .. | .. |
|---|
| 837 | 914 | if (err) |
|---|
| 838 | 915 | return err; |
|---|
| 839 | 916 | |
|---|
| 840 | | - sup = ubifs_read_sb_node(c); |
|---|
| 841 | | - if (IS_ERR(sup)) |
|---|
| 842 | | - return PTR_ERR(sup); |
|---|
| 843 | | - |
|---|
| 844 | 917 | /* Free-space fixup is no longer required */ |
|---|
| 845 | 918 | c->space_fixup = 0; |
|---|
| 846 | 919 | sup->flags &= cpu_to_le32(~UBIFS_FLG_SPACE_FIXUP); |
|---|
| 847 | 920 | |
|---|
| 848 | | - err = ubifs_write_sb_node(c, sup); |
|---|
| 849 | | - kfree(sup); |
|---|
| 850 | | - if (err) |
|---|
| 851 | | - return err; |
|---|
| 921 | + c->superblock_need_write = 1; |
|---|
| 852 | 922 | |
|---|
| 853 | 923 | ubifs_msg(c, "free space fixup complete"); |
|---|
| 854 | 924 | return err; |
|---|
| .. | .. |
|---|
| 857 | 927 | int ubifs_enable_encryption(struct ubifs_info *c) |
|---|
| 858 | 928 | { |
|---|
| 859 | 929 | int err; |
|---|
| 860 | | - struct ubifs_sb_node *sup; |
|---|
| 930 | + struct ubifs_sb_node *sup = c->sup_node; |
|---|
| 931 | + |
|---|
| 932 | + if (!IS_ENABLED(CONFIG_FS_ENCRYPTION)) |
|---|
| 933 | + return -EOPNOTSUPP; |
|---|
| 861 | 934 | |
|---|
| 862 | 935 | if (c->encrypted) |
|---|
| 863 | 936 | return 0; |
|---|
| .. | .. |
|---|
| 870 | 943 | return -EINVAL; |
|---|
| 871 | 944 | } |
|---|
| 872 | 945 | |
|---|
| 873 | | - sup = ubifs_read_sb_node(c); |
|---|
| 874 | | - if (IS_ERR(sup)) |
|---|
| 875 | | - return PTR_ERR(sup); |
|---|
| 876 | | - |
|---|
| 877 | 946 | sup->flags |= cpu_to_le32(UBIFS_FLG_ENCRYPTION); |
|---|
| 878 | 947 | |
|---|
| 879 | 948 | err = ubifs_write_sb_node(c, sup); |
|---|
| 880 | 949 | if (!err) |
|---|
| 881 | 950 | c->encrypted = 1; |
|---|
| 882 | | - kfree(sup); |
|---|
| 883 | 951 | |
|---|
| 884 | 952 | return err; |
|---|
| 885 | 953 | } |
|---|