hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/ubifs/super.c
....@@ -1,20 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * This file is part of UBIFS.
34 *
45 * 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
186 *
197 * Authors: Artem Bityutskiy (Битюцкий Артём)
208 * Adrian Hunter
....@@ -37,6 +25,24 @@
3725 #include <linux/math64.h>
3826 #include <linux/writeback.h>
3927 #include "ubifs.h"
28
+
29
+static int ubifs_default_version_set(const char *val, const struct kernel_param *kp)
30
+{
31
+ int n = 0, ret;
32
+
33
+ ret = kstrtoint(val, 10, &n);
34
+ if (ret != 0 || n < 4 || n > UBIFS_FORMAT_VERSION)
35
+ return -EINVAL;
36
+ return param_set_int(val, kp);
37
+}
38
+
39
+static const struct kernel_param_ops ubifs_default_version_ops = {
40
+ .set = ubifs_default_version_set,
41
+ .get = param_get_int,
42
+};
43
+
44
+int ubifs_default_version = UBIFS_FORMAT_VERSION;
45
+module_param_cb(default_version, &ubifs_default_version_ops, &ubifs_default_version, 0600);
4046
4147 /*
4248 * Maximum amount of memory we may 'kmalloc()' without worrying that we are
....@@ -129,9 +135,10 @@
129135 goto out_ino;
130136
131137 inode->i_flags |= S_NOCMTIME;
132
-#ifndef CONFIG_UBIFS_ATIME_SUPPORT
133
- inode->i_flags |= S_NOATIME;
134
-#endif
138
+
139
+ if (!IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT))
140
+ inode->i_flags |= S_NOATIME;
141
+
135142 set_nlink(inode, le32_to_cpu(ino->nlink));
136143 i_uid_write(inode, le32_to_cpu(ino->uid));
137144 i_gid_write(inode, le32_to_cpu(ino->gid));
....@@ -268,25 +275,19 @@
268275 memset((void *)ui + sizeof(struct inode), 0,
269276 sizeof(struct ubifs_inode) - sizeof(struct inode));
270277 mutex_init(&ui->ui_mutex);
278
+ init_rwsem(&ui->xattr_sem);
271279 spin_lock_init(&ui->ui_lock);
272280 return &ui->vfs_inode;
273281 };
274282
275
-static void ubifs_i_callback(struct rcu_head *head)
276
-{
277
- struct inode *inode = container_of(head, struct inode, i_rcu);
278
- struct ubifs_inode *ui = ubifs_inode(inode);
279
-
280
- fscrypt_free_inode(inode);
281
- kmem_cache_free(ubifs_inode_slab, ui);
282
-}
283
-
284
-static void ubifs_destroy_inode(struct inode *inode)
283
+static void ubifs_free_inode(struct inode *inode)
285284 {
286285 struct ubifs_inode *ui = ubifs_inode(inode);
287286
288287 kfree(ui->data);
289
- call_rcu(&inode->i_rcu, ubifs_i_callback);
288
+ fscrypt_free_inode(inode);
289
+
290
+ kmem_cache_free(ubifs_inode_slab, ui);
290291 }
291292
292293 /*
....@@ -591,6 +592,11 @@
591592 c->ranges[UBIFS_REF_NODE].len = UBIFS_REF_NODE_SZ;
592593 c->ranges[UBIFS_TRUN_NODE].len = UBIFS_TRUN_NODE_SZ;
593594 c->ranges[UBIFS_CS_NODE].len = UBIFS_CS_NODE_SZ;
595
+ c->ranges[UBIFS_AUTH_NODE].min_len = UBIFS_AUTH_NODE_SZ;
596
+ c->ranges[UBIFS_AUTH_NODE].max_len = UBIFS_AUTH_NODE_SZ +
597
+ UBIFS_MAX_HMAC_LEN;
598
+ c->ranges[UBIFS_SIG_NODE].min_len = UBIFS_SIG_NODE_SZ;
599
+ c->ranges[UBIFS_SIG_NODE].max_len = c->leb_size - UBIFS_SB_NODE_SZ;
594600
595601 c->ranges[UBIFS_INO_NODE].min_len = UBIFS_INO_NODE_SZ;
596602 c->ranges[UBIFS_INO_NODE].max_len = UBIFS_MAX_INO_NODE_SZ;
....@@ -632,6 +638,10 @@
632638 c->max_bu_buf_len = UBIFS_MAX_BULK_READ * UBIFS_MAX_DATA_NODE_SZ;
633639 if (c->max_bu_buf_len > c->leb_size)
634640 c->max_bu_buf_len = c->leb_size;
641
+
642
+ /* Log is ready, preserve one LEB for commits. */
643
+ c->min_log_bytes = c->leb_size;
644
+
635645 return 0;
636646 }
637647
....@@ -823,11 +833,16 @@
823833 INIT_LIST_HEAD(&c->jheads[i].buds_list);
824834 err = ubifs_wbuf_init(c, &c->jheads[i].wbuf);
825835 if (err)
826
- return err;
836
+ goto out_wbuf;
827837
828838 c->jheads[i].wbuf.sync_callback = &bud_wbuf_callback;
829839 c->jheads[i].wbuf.jhead = i;
830840 c->jheads[i].grouped = 1;
841
+ c->jheads[i].log_hash = ubifs_hash_get_desc(c);
842
+ if (IS_ERR(c->jheads[i].log_hash)) {
843
+ err = PTR_ERR(c->jheads[i].log_hash);
844
+ goto out_log_hash;
845
+ }
831846 }
832847
833848 /*
....@@ -838,6 +853,21 @@
838853 c->jheads[GCHD].grouped = 0;
839854
840855 return 0;
856
+
857
+out_log_hash:
858
+ kfree(c->jheads[i].wbuf.buf);
859
+ kfree(c->jheads[i].wbuf.inodes);
860
+
861
+out_wbuf:
862
+ while (i--) {
863
+ kfree(c->jheads[i].wbuf.buf);
864
+ kfree(c->jheads[i].wbuf.inodes);
865
+ kfree(c->jheads[i].log_hash);
866
+ }
867
+ kfree(c->jheads);
868
+ c->jheads = NULL;
869
+
870
+ return err;
841871 }
842872
843873 /**
....@@ -852,6 +882,7 @@
852882 for (i = 0; i < c->jhead_cnt; i++) {
853883 kfree(c->jheads[i].wbuf.buf);
854884 kfree(c->jheads[i].wbuf.inodes);
885
+ kfree(c->jheads[i].log_hash);
855886 }
856887 kfree(c->jheads);
857888 c->jheads = NULL;
....@@ -936,6 +967,8 @@
936967 * Opt_no_chk_data_crc: do not check CRCs when reading data nodes
937968 * Opt_override_compr: override default compressor
938969 * Opt_assert: set ubifs_assert() action
970
+ * Opt_auth_key: The key name used for authentication
971
+ * Opt_auth_hash_name: The hash type used for authentication
939972 * Opt_err: just end of array marker
940973 */
941974 enum {
....@@ -947,6 +980,8 @@
947980 Opt_no_chk_data_crc,
948981 Opt_override_compr,
949982 Opt_assert,
983
+ Opt_auth_key,
984
+ Opt_auth_hash_name,
950985 Opt_ignore,
951986 Opt_err,
952987 };
....@@ -959,6 +994,8 @@
959994 {Opt_chk_data_crc, "chk_data_crc"},
960995 {Opt_no_chk_data_crc, "no_chk_data_crc"},
961996 {Opt_override_compr, "compr=%s"},
997
+ {Opt_auth_key, "auth_key=%s"},
998
+ {Opt_auth_hash_name, "auth_hash_name=%s"},
962999 {Opt_ignore, "ubi=%s"},
9631000 {Opt_ignore, "vol=%s"},
9641001 {Opt_assert, "assert=%s"},
....@@ -1052,6 +1089,8 @@
10521089 c->mount_opts.compr_type = UBIFS_COMPR_LZO;
10531090 else if (!strcmp(name, "zlib"))
10541091 c->mount_opts.compr_type = UBIFS_COMPR_ZLIB;
1092
+ else if (!strcmp(name, "zstd"))
1093
+ c->mount_opts.compr_type = UBIFS_COMPR_ZSTD;
10551094 else {
10561095 ubifs_err(c, "unknown compressor \"%s\"", name); //FIXME: is c ready?
10571096 kfree(name);
....@@ -1082,6 +1121,22 @@
10821121 kfree(act);
10831122 break;
10841123 }
1124
+ case Opt_auth_key:
1125
+ if (!is_remount) {
1126
+ c->auth_key_name = kstrdup(args[0].from,
1127
+ GFP_KERNEL);
1128
+ if (!c->auth_key_name)
1129
+ return -ENOMEM;
1130
+ }
1131
+ break;
1132
+ case Opt_auth_hash_name:
1133
+ if (!is_remount) {
1134
+ c->auth_hash_name = kstrdup(args[0].from,
1135
+ GFP_KERNEL);
1136
+ if (!c->auth_hash_name)
1137
+ return -ENOMEM;
1138
+ }
1139
+ break;
10851140 case Opt_ignore:
10861141 break;
10871142 default:
....@@ -1102,6 +1157,18 @@
11021157 }
11031158
11041159 return 0;
1160
+}
1161
+
1162
+/*
1163
+ * ubifs_release_options - release mount parameters which have been dumped.
1164
+ * @c: UBIFS file-system description object
1165
+ */
1166
+static void ubifs_release_options(struct ubifs_info *c)
1167
+{
1168
+ kfree(c->auth_key_name);
1169
+ c->auth_key_name = NULL;
1170
+ kfree(c->auth_hash_name);
1171
+ c->auth_hash_name = NULL;
11051172 }
11061173
11071174 /**
....@@ -1261,9 +1328,22 @@
12611328
12621329 c->mounting = 1;
12631330
1331
+ if (c->auth_key_name) {
1332
+ if (IS_ENABLED(CONFIG_UBIFS_FS_AUTHENTICATION)) {
1333
+ err = ubifs_init_authentication(c);
1334
+ if (err)
1335
+ goto out_free;
1336
+ } else {
1337
+ ubifs_err(c, "auth_key_name, but UBIFS is built without"
1338
+ " authentication support");
1339
+ err = -EINVAL;
1340
+ goto out_free;
1341
+ }
1342
+ }
1343
+
12641344 err = ubifs_read_superblock(c);
12651345 if (err)
1266
- goto out_free;
1346
+ goto out_auth;
12671347
12681348 c->probing = 0;
12691349
....@@ -1275,19 +1355,18 @@
12751355 ubifs_err(c, "'compressor \"%s\" is not compiled in",
12761356 ubifs_compr_name(c, c->default_compr));
12771357 err = -ENOTSUPP;
1278
- goto out_free;
1358
+ goto out_auth;
12791359 }
12801360
12811361 err = init_constants_sb(c);
12821362 if (err)
1283
- goto out_free;
1363
+ goto out_auth;
12841364
1285
- sz = ALIGN(c->max_idx_node_sz, c->min_io_size);
1286
- sz = ALIGN(sz + c->max_idx_node_sz, c->min_io_size);
1365
+ sz = ALIGN(c->max_idx_node_sz, c->min_io_size) * 2;
12871366 c->cbuf = kmalloc(sz, GFP_NOFS);
12881367 if (!c->cbuf) {
12891368 err = -ENOMEM;
1290
- goto out_free;
1369
+ goto out_auth;
12911370 }
12921371
12931372 err = alloc_wbufs(c);
....@@ -1346,6 +1425,26 @@
13461425 goto out_lpt;
13471426 }
13481427
1428
+ /*
1429
+ * Handle offline signed images: Now that the master node is
1430
+ * written and its validation no longer depends on the hash
1431
+ * in the superblock, we can update the offline signed
1432
+ * superblock with a HMAC version,
1433
+ */
1434
+ if (ubifs_authenticated(c) && ubifs_hmac_zero(c, c->sup_node->hmac)) {
1435
+ err = ubifs_hmac_wkm(c, c->sup_node->hmac_wkm);
1436
+ if (err)
1437
+ goto out_lpt;
1438
+ c->superblock_need_write = 1;
1439
+ }
1440
+
1441
+ if (!c->ro_mount && c->superblock_need_write) {
1442
+ err = ubifs_write_sb_node(c, c->sup_node);
1443
+ if (err)
1444
+ goto out_lpt;
1445
+ c->superblock_need_write = 0;
1446
+ }
1447
+
13491448 err = dbg_check_idx_size(c, c->bi.old_idx_sz);
13501449 if (err)
13511450 goto out_lpt;
....@@ -1379,12 +1478,21 @@
13791478 }
13801479
13811480 if (c->need_recovery) {
1382
- err = ubifs_recover_size(c);
1383
- if (err)
1384
- goto out_orphans;
1481
+ if (!ubifs_authenticated(c)) {
1482
+ err = ubifs_recover_size(c, true);
1483
+ if (err)
1484
+ goto out_orphans;
1485
+ }
1486
+
13851487 err = ubifs_rcvry_gc_commit(c);
13861488 if (err)
13871489 goto out_orphans;
1490
+
1491
+ if (ubifs_authenticated(c)) {
1492
+ err = ubifs_recover_size(c, false);
1493
+ if (err)
1494
+ goto out_orphans;
1495
+ }
13881496 } else {
13891497 err = take_gc_lnum(c);
13901498 if (err)
....@@ -1403,7 +1511,7 @@
14031511 if (err)
14041512 goto out_orphans;
14051513 } else if (c->need_recovery) {
1406
- err = ubifs_recover_size(c);
1514
+ err = ubifs_recover_size(c, false);
14071515 if (err)
14081516 goto out_orphans;
14091517 } else {
....@@ -1442,9 +1550,7 @@
14421550 if (err)
14431551 goto out_infos;
14441552
1445
- err = dbg_debugfs_init_fs(c);
1446
- if (err)
1447
- goto out_infos;
1553
+ dbg_debugfs_init_fs(c);
14481554
14491555 c->mounting = 0;
14501556
....@@ -1511,6 +1617,8 @@
15111617 c->bud_bytes, c->bud_bytes >> 10, c->bud_bytes >> 20);
15121618 dbg_gen("max. seq. number: %llu", c->max_sqnum);
15131619 dbg_gen("commit number: %llu", c->cmt_no);
1620
+ dbg_gen("max. xattrs per inode: %d", ubifs_xattr_max_cnt(c));
1621
+ dbg_gen("max orphans: %d", c->max_orphans);
15141622
15151623 return 0;
15161624
....@@ -1533,12 +1641,15 @@
15331641 free_wbufs(c);
15341642 out_cbuf:
15351643 kfree(c->cbuf);
1644
+out_auth:
1645
+ ubifs_exit_authentication(c);
15361646 out_free:
15371647 kfree(c->write_reserve_buf);
15381648 kfree(c->bu.buf);
15391649 vfree(c->ileb_buf);
15401650 vfree(c->sbuf);
15411651 kfree(c->bottom_up_buf);
1652
+ kfree(c->sup_node);
15421653 ubifs_debugging_exit(c);
15431654 return err;
15441655 }
....@@ -1569,7 +1680,9 @@
15691680 free_wbufs(c);
15701681 free_orphans(c);
15711682 ubifs_lpt_free(c, 0);
1683
+ ubifs_exit_authentication(c);
15721684
1685
+ ubifs_release_options(c);
15731686 kfree(c->cbuf);
15741687 kfree(c->rcvrd_mst_node);
15751688 kfree(c->mst_node);
....@@ -1578,6 +1691,7 @@
15781691 vfree(c->ileb_buf);
15791692 vfree(c->sbuf);
15801693 kfree(c->bottom_up_buf);
1694
+ kfree(c->sup_node);
15811695 ubifs_debugging_exit(c);
15821696 }
15831697
....@@ -1616,29 +1730,16 @@
16161730 if (err)
16171731 goto out;
16181732
1619
- if (c->old_leb_cnt != c->leb_cnt) {
1620
- struct ubifs_sb_node *sup;
1621
-
1622
- sup = ubifs_read_sb_node(c);
1623
- if (IS_ERR(sup)) {
1624
- err = PTR_ERR(sup);
1625
- goto out;
1626
- }
1627
- sup->leb_cnt = cpu_to_le32(c->leb_cnt);
1628
- err = ubifs_write_sb_node(c, sup);
1629
- kfree(sup);
1630
- if (err)
1631
- goto out;
1632
- }
1633
-
16341733 if (c->need_recovery) {
16351734 ubifs_msg(c, "completing deferred recovery");
16361735 err = ubifs_write_rcvrd_mst_node(c);
16371736 if (err)
16381737 goto out;
1639
- err = ubifs_recover_size(c);
1640
- if (err)
1641
- goto out;
1738
+ if (!ubifs_authenticated(c)) {
1739
+ err = ubifs_recover_size(c, true);
1740
+ if (err)
1741
+ goto out;
1742
+ }
16421743 err = ubifs_clean_lebs(c, c->sbuf);
16431744 if (err)
16441745 goto out;
....@@ -1658,6 +1759,16 @@
16581759 err = ubifs_write_master(c);
16591760 if (err)
16601761 goto out;
1762
+ }
1763
+
1764
+ if (c->superblock_need_write) {
1765
+ struct ubifs_sb_node *sup = c->sup_node;
1766
+
1767
+ err = ubifs_write_sb_node(c, sup);
1768
+ if (err)
1769
+ goto out;
1770
+
1771
+ c->superblock_need_write = 0;
16611772 }
16621773
16631774 c->ileb_buf = vmalloc(c->leb_size);
....@@ -1704,10 +1815,19 @@
17041815 goto out;
17051816 }
17061817
1707
- if (c->need_recovery)
1818
+ if (c->need_recovery) {
17081819 err = ubifs_rcvry_gc_commit(c);
1709
- else
1820
+ if (err)
1821
+ goto out;
1822
+
1823
+ if (ubifs_authenticated(c)) {
1824
+ err = ubifs_recover_size(c, false);
1825
+ if (err)
1826
+ goto out;
1827
+ }
1828
+ } else {
17101829 err = ubifs_leb_unmap(c, c->gc_lnum);
1830
+ }
17111831 if (err)
17121832 goto out;
17131833
....@@ -1931,7 +2051,7 @@
19312051
19322052 const struct super_operations ubifs_super_operations = {
19332053 .alloc_inode = ubifs_alloc_inode,
1934
- .destroy_inode = ubifs_destroy_inode,
2054
+ .free_inode = ubifs_free_inode,
19352055 .put_super = ubifs_put_super,
19362056 .write_inode = ubifs_write_inode,
19372057 .drop_inode = ubifs_drop_inode,
....@@ -2087,6 +2207,8 @@
20872207 c->vi.vol_id);
20882208 if (err)
20892209 goto out_close;
2210
+ sb->s_bdi->ra_pages = 0;
2211
+ sb->s_bdi->io_pages = 0;
20902212
20912213 sb->s_fs_info = c;
20922214 sb->s_magic = UBIFS_SUPER_MAGIC;
....@@ -2099,9 +2221,7 @@
20992221 #ifdef CONFIG_UBIFS_FS_XATTR
21002222 sb->s_xattr = ubifs_xattr_handlers;
21012223 #endif
2102
-#ifdef CONFIG_FS_ENCRYPTION
2103
- sb->s_cop = &ubifs_crypt_operations;
2104
-#endif
2224
+ fscrypt_set_ops(sb, &ubifs_crypt_operations);
21052225
21062226 mutex_lock(&c->umount_mutex);
21072227 err = mount_ubifs(c);
....@@ -2131,6 +2251,7 @@
21312251 out_unlock:
21322252 mutex_unlock(&c->umount_mutex);
21332253 out_close:
2254
+ ubifs_release_options(c);
21342255 ubi_close_volume(c->ubi);
21352256 out:
21362257 return err;
....@@ -2203,11 +2324,10 @@
22032324 goto out_deact;
22042325 /* We do not support atime */
22052326 sb->s_flags |= SB_ACTIVE;
2206
-#ifndef CONFIG_UBIFS_ATIME_SUPPORT
2207
- sb->s_flags |= SB_NOATIME;
2208
-#else
2209
- ubifs_msg(c, "full atime support is enabled.");
2210
-#endif
2327
+ if (IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT))
2328
+ ubifs_msg(c, "full atime support is enabled.");
2329
+ else
2330
+ sb->s_flags |= SB_NOATIME;
22112331 }
22122332
22132333 /* 'fill_super()' opens ubi again so we must close it here */
....@@ -2322,9 +2442,7 @@
23222442 if (err)
23232443 goto out_shrinker;
23242444
2325
- err = dbg_debugfs_init();
2326
- if (err)
2327
- goto out_compr;
2445
+ dbg_debugfs_init();
23282446
23292447 err = register_filesystem(&ubifs_fs_type);
23302448 if (err) {
....@@ -2336,7 +2454,6 @@
23362454
23372455 out_dbg:
23382456 dbg_debugfs_exit();
2339
-out_compr:
23402457 ubifs_compressors_exit();
23412458 out_shrinker:
23422459 unregister_shrinker(&ubifs_shrinker_info);
....@@ -2367,6 +2484,7 @@
23672484 module_exit(ubifs_exit);
23682485
23692486 MODULE_LICENSE("GPL");
2487
+MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY);
23702488 MODULE_VERSION(__stringify(UBIFS_VERSION));
23712489 MODULE_AUTHOR("Artem Bityutskiy, Adrian Hunter");
23722490 MODULE_DESCRIPTION("UBIFS - UBI File System");