| .. | .. | 
|---|
 | 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 | 
|---|
| .. | .. | 
|---|
| 39 | 27 |  #include <linux/security.h> | 
|---|
| 40 | 28 |  #include <linux/xattr.h> | 
|---|
| 41 | 29 |  #include <linux/random.h> | 
|---|
 | 30 | +#include <crypto/hash_info.h>  | 
|---|
 | 31 | +#include <crypto/hash.h>  | 
|---|
 | 32 | +#include <crypto/algapi.h>  | 
|---|
| 42 | 33 |   | 
|---|
| 43 | 34 |  #include <linux/fscrypt.h> | 
|---|
| 44 | 35 |   | 
|---|
| .. | .. | 
|---|
| 155 | 146 |   | 
|---|
| 156 | 147 |  /* Maximum number of data nodes to bulk-read */ | 
|---|
| 157 | 148 |  #define UBIFS_MAX_BULK_READ 32 | 
|---|
 | 149 | +  | 
|---|
 | 150 | +#ifdef CONFIG_UBIFS_FS_AUTHENTICATION  | 
|---|
 | 151 | +#define UBIFS_HASH_ARR_SZ UBIFS_MAX_HASH_LEN  | 
|---|
 | 152 | +#define UBIFS_HMAC_ARR_SZ UBIFS_MAX_HMAC_LEN  | 
|---|
 | 153 | +#else  | 
|---|
 | 154 | +#define UBIFS_HASH_ARR_SZ 0  | 
|---|
 | 155 | +#define UBIFS_HMAC_ARR_SZ 0  | 
|---|
 | 156 | +#endif  | 
|---|
| 158 | 157 |   | 
|---|
| 159 | 158 |  /* | 
|---|
| 160 | 159 |   * Lockdep classes for UBIFS inode @ui_mutex. | 
|---|
| .. | .. | 
|---|
| 357 | 356 |   * @ui_mutex: serializes inode write-back with the rest of VFS operations, | 
|---|
| 358 | 357 |   *            serializes "clean <-> dirty" state changes, serializes bulk-read, | 
|---|
| 359 | 358 |   *            protects @dirty, @bulk_read, @ui_size, and @xattr_size | 
|---|
 | 359 | + * @xattr_sem: serilizes write operations (remove|set|create) on xattr  | 
|---|
| 360 | 360 |   * @ui_lock: protects @synced_i_size | 
|---|
| 361 | 361 |   * @synced_i_size: synchronized size of inode, i.e. the value of inode size | 
|---|
| 362 | 362 |   *                 currently stored on the flash; used only for regular file | 
|---|
| .. | .. | 
|---|
| 410 | 410 |  	unsigned int bulk_read:1; | 
|---|
| 411 | 411 |  	unsigned int compr_type:2; | 
|---|
| 412 | 412 |  	struct mutex ui_mutex; | 
|---|
 | 413 | +	struct rw_semaphore xattr_sem;  | 
|---|
| 413 | 414 |  	spinlock_t ui_lock; | 
|---|
| 414 | 415 |  	loff_t synced_i_size; | 
|---|
| 415 | 416 |  	loff_t ui_size; | 
|---|
| .. | .. | 
|---|
| 705 | 706 |   * @jhead: journal head number this bud belongs to | 
|---|
| 706 | 707 |   * @list: link in the list buds belonging to the same journal head | 
|---|
| 707 | 708 |   * @rb: link in the tree of all buds | 
|---|
 | 709 | + * @log_hash: the log hash from the commit start node up to this bud  | 
|---|
| 708 | 710 |   */ | 
|---|
| 709 | 711 |  struct ubifs_bud { | 
|---|
| 710 | 712 |  	int lnum; | 
|---|
| .. | .. | 
|---|
| 712 | 714 |  	int jhead; | 
|---|
| 713 | 715 |  	struct list_head list; | 
|---|
| 714 | 716 |  	struct rb_node rb; | 
|---|
 | 717 | +	struct shash_desc *log_hash;  | 
|---|
| 715 | 718 |  }; | 
|---|
| 716 | 719 |   | 
|---|
| 717 | 720 |  /** | 
|---|
| .. | .. | 
|---|
| 719 | 722 |   * @wbuf: head's write-buffer | 
|---|
| 720 | 723 |   * @buds_list: list of bud LEBs belonging to this journal head | 
|---|
| 721 | 724 |   * @grouped: non-zero if UBIFS groups nodes when writing to this journal head | 
|---|
 | 725 | + * @log_hash: the log hash from the commit start node up to this journal head  | 
|---|
| 722 | 726 |   * | 
|---|
| 723 | 727 |   * Note, the @buds list is protected by the @c->buds_lock. | 
|---|
| 724 | 728 |   */ | 
|---|
| .. | .. | 
|---|
| 726 | 730 |  	struct ubifs_wbuf wbuf; | 
|---|
| 727 | 731 |  	struct list_head buds_list; | 
|---|
| 728 | 732 |  	unsigned int grouped:1; | 
|---|
 | 733 | +	struct shash_desc *log_hash;  | 
|---|
| 729 | 734 |  }; | 
|---|
| 730 | 735 |   | 
|---|
| 731 | 736 |  /** | 
|---|
| .. | .. | 
|---|
| 735 | 740 |   * @lnum: LEB number of the target node (indexing node or data node) | 
|---|
| 736 | 741 |   * @offs: target node offset within @lnum | 
|---|
| 737 | 742 |   * @len: target node length | 
|---|
 | 743 | + * @hash: the hash of the target node  | 
|---|
| 738 | 744 |   */ | 
|---|
| 739 | 745 |  struct ubifs_zbranch { | 
|---|
| 740 | 746 |  	union ubifs_key key; | 
|---|
| .. | .. | 
|---|
| 745 | 751 |  	int lnum; | 
|---|
| 746 | 752 |  	int offs; | 
|---|
| 747 | 753 |  	int len; | 
|---|
 | 754 | +	u8 hash[UBIFS_HASH_ARR_SZ];  | 
|---|
| 748 | 755 |  }; | 
|---|
| 749 | 756 |   | 
|---|
| 750 | 757 |  /** | 
|---|
| 751 | 758 |   * struct ubifs_znode - in-memory representation of an indexing node. | 
|---|
| 752 | 759 |   * @parent: parent znode or NULL if it is the root | 
|---|
| 753 | 760 |   * @cnext: next znode to commit | 
|---|
 | 761 | + * @cparent: parent node for this commit  | 
|---|
 | 762 | + * @ciip: index in cparent's zbranch array  | 
|---|
| 754 | 763 |   * @flags: znode flags (%DIRTY_ZNODE, %COW_ZNODE or %OBSOLETE_ZNODE) | 
|---|
| 755 | 764 |   * @time: last access time (seconds) | 
|---|
| 756 | 765 |   * @level: level of the entry in the TNC tree | 
|---|
| .. | .. | 
|---|
| 768 | 777 |  struct ubifs_znode { | 
|---|
| 769 | 778 |  	struct ubifs_znode *parent; | 
|---|
| 770 | 779 |  	struct ubifs_znode *cnext; | 
|---|
 | 780 | +	struct ubifs_znode *cparent;  | 
|---|
 | 781 | +	int ciip;  | 
|---|
| 771 | 782 |  	unsigned long flags; | 
|---|
| 772 | 783 |  	time64_t time; | 
|---|
| 773 | 784 |  	int level; | 
|---|
| .. | .. | 
|---|
| 903 | 914 |   * @rb: rb-tree node of rb-tree of orphans sorted by inode number | 
|---|
| 904 | 915 |   * @list: list head of list of orphans in order added | 
|---|
| 905 | 916 |   * @new_list: list head of list of orphans added since the last commit | 
|---|
 | 917 | + * @child_list: list of xattr childs if this orphan hosts xattrs, list head  | 
|---|
 | 918 | + * if this orphan is a xattr, not used otherwise.  | 
|---|
| 906 | 919 |   * @cnext: next orphan to commit | 
|---|
| 907 | 920 |   * @dnext: next orphan to delete | 
|---|
| 908 | 921 |   * @inum: inode number | 
|---|
| .. | .. | 
|---|
| 914 | 927 |  	struct rb_node rb; | 
|---|
| 915 | 928 |  	struct list_head list; | 
|---|
| 916 | 929 |  	struct list_head new_list; | 
|---|
 | 930 | +	struct list_head child_list;  | 
|---|
| 917 | 931 |  	struct ubifs_orphan *cnext; | 
|---|
| 918 | 932 |  	struct ubifs_orphan *dnext; | 
|---|
| 919 | 933 |  	ino_t inum; | 
|---|
| .. | .. | 
|---|
| 982 | 996 |   * struct ubifs_info - UBIFS file-system description data structure | 
|---|
| 983 | 997 |   * (per-superblock). | 
|---|
| 984 | 998 |   * @vfs_sb: VFS @struct super_block object | 
|---|
 | 999 | + * @sup_node: The super block node as read from the device  | 
|---|
| 985 | 1000 |   * | 
|---|
| 986 | 1001 |   * @highest_inum: highest used inode number | 
|---|
| 987 | 1002 |   * @max_sqnum: current global sequence number | 
|---|
| .. | .. | 
|---|
| 1027 | 1042 |   * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) | 
|---|
| 1028 | 1043 |   * @rw_incompat: the media is not R/W compatible | 
|---|
| 1029 | 1044 |   * @assert_action: action to take when a ubifs_assert() fails | 
|---|
 | 1045 | + * @authenticated: flag indigating the FS is mounted in authenticated mode  | 
|---|
| 1030 | 1046 |   * | 
|---|
| 1031 | 1047 |   * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and | 
|---|
| 1032 | 1048 |   *             @calc_idx_sz | 
|---|
| .. | .. | 
|---|
| 1074 | 1090 |   * @key_hash: direntry key hash function | 
|---|
| 1075 | 1091 |   * @key_fmt: key format | 
|---|
| 1076 | 1092 |   * @key_len: key length | 
|---|
 | 1093 | + * @hash_len: The length of the index node hashes  | 
|---|
| 1077 | 1094 |   * @fanout: fanout of the index tree (number of links per indexing node) | 
|---|
| 1078 | 1095 |   * | 
|---|
| 1079 | 1096 |   * @min_io_size: minimal input/output unit size | 
|---|
| .. | .. | 
|---|
| 1089 | 1106 |   *                used to store indexing nodes (@leb_size - @max_idx_node_sz) | 
|---|
| 1090 | 1107 |   * @leb_cnt: count of logical eraseblocks | 
|---|
| 1091 | 1108 |   * @max_leb_cnt: maximum count of logical eraseblocks | 
|---|
| 1092 |  | - * @old_leb_cnt: count of logical eraseblocks before re-size  | 
|---|
| 1093 | 1109 |   * @ro_media: the underlying UBI volume is read-only | 
|---|
| 1094 | 1110 |   * @ro_mount: the file-system was mounted as read-only | 
|---|
| 1095 | 1111 |   * @ro_error: UBIFS switched to R/O mode because an error happened | 
|---|
| .. | .. | 
|---|
| 1209 | 1225 |   * @rp_uid: reserved pool user ID | 
|---|
| 1210 | 1226 |   * @rp_gid: reserved pool group ID | 
|---|
| 1211 | 1227 |   * | 
|---|
 | 1228 | + * @hash_tfm: the hash transformation used for hashing nodes  | 
|---|
 | 1229 | + * @hmac_tfm: the HMAC transformation for this filesystem  | 
|---|
 | 1230 | + * @hmac_desc_len: length of the HMAC used for authentication  | 
|---|
 | 1231 | + * @auth_key_name: the authentication key name  | 
|---|
 | 1232 | + * @auth_hash_name: the name of the hash algorithm used for authentication  | 
|---|
 | 1233 | + * @auth_hash_algo: the authentication hash used for this fs  | 
|---|
 | 1234 | + * @log_hash: the log hash from the commit start node up to the latest reference  | 
|---|
 | 1235 | + *            node.  | 
|---|
 | 1236 | + *  | 
|---|
| 1212 | 1237 |   * @empty: %1 if the UBI device is empty | 
|---|
| 1213 | 1238 |   * @need_recovery: %1 if the file-system needs recovery | 
|---|
| 1214 | 1239 |   * @replaying: %1 during journal replay | 
|---|
| .. | .. | 
|---|
| 1229 | 1254 |   */ | 
|---|
| 1230 | 1255 |  struct ubifs_info { | 
|---|
| 1231 | 1256 |  	struct super_block *vfs_sb; | 
|---|
 | 1257 | +	struct ubifs_sb_node *sup_node;  | 
|---|
| 1232 | 1258 |   | 
|---|
| 1233 | 1259 |  	ino_t highest_inum; | 
|---|
| 1234 | 1260 |  	unsigned long long max_sqnum; | 
|---|
| .. | .. | 
|---|
| 1269 | 1295 |  	unsigned int default_compr:2; | 
|---|
| 1270 | 1296 |  	unsigned int rw_incompat:1; | 
|---|
| 1271 | 1297 |  	unsigned int assert_action:2; | 
|---|
 | 1298 | +	unsigned int authenticated:1;  | 
|---|
 | 1299 | +	unsigned int superblock_need_write:1;  | 
|---|
| 1272 | 1300 |   | 
|---|
| 1273 | 1301 |  	struct mutex tnc_mutex; | 
|---|
| 1274 | 1302 |  	struct ubifs_zbranch zroot; | 
|---|
| .. | .. | 
|---|
| 1313 | 1341 |  	uint32_t (*key_hash)(const char *str, int len); | 
|---|
| 1314 | 1342 |  	int key_fmt; | 
|---|
| 1315 | 1343 |  	int key_len; | 
|---|
 | 1344 | +	int hash_len;  | 
|---|
| 1316 | 1345 |  	int fanout; | 
|---|
| 1317 | 1346 |   | 
|---|
| 1318 | 1347 |  	int min_io_size; | 
|---|
| .. | .. | 
|---|
| 1325 | 1354 |  	int idx_leb_size; | 
|---|
| 1326 | 1355 |  	int leb_cnt; | 
|---|
| 1327 | 1356 |  	int max_leb_cnt; | 
|---|
| 1328 |  | -	int old_leb_cnt;  | 
|---|
| 1329 | 1357 |  	unsigned int ro_media:1; | 
|---|
| 1330 | 1358 |  	unsigned int ro_mount:1; | 
|---|
| 1331 | 1359 |  	unsigned int ro_error:1; | 
|---|
| .. | .. | 
|---|
| 1440 | 1468 |  	kuid_t rp_uid; | 
|---|
| 1441 | 1469 |  	kgid_t rp_gid; | 
|---|
| 1442 | 1470 |   | 
|---|
 | 1471 | +	struct crypto_shash *hash_tfm;  | 
|---|
 | 1472 | +	struct crypto_shash *hmac_tfm;  | 
|---|
 | 1473 | +	int hmac_desc_len;  | 
|---|
 | 1474 | +	char *auth_key_name;  | 
|---|
 | 1475 | +	char *auth_hash_name;  | 
|---|
 | 1476 | +	enum hash_algo auth_hash_algo;  | 
|---|
 | 1477 | +  | 
|---|
 | 1478 | +	struct shash_desc *log_hash;  | 
|---|
 | 1479 | +  | 
|---|
| 1443 | 1480 |  	/* The below fields are used only during mounting and re-mounting */ | 
|---|
| 1444 | 1481 |  	unsigned int empty:1; | 
|---|
| 1445 | 1482 |  	unsigned int need_recovery:1; | 
|---|
| .. | .. | 
|---|
| 1469 | 1506 |  extern const struct inode_operations ubifs_dir_inode_operations; | 
|---|
| 1470 | 1507 |  extern const struct inode_operations ubifs_symlink_inode_operations; | 
|---|
| 1471 | 1508 |  extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; | 
|---|
 | 1509 | +extern int ubifs_default_version;  | 
|---|
 | 1510 | +  | 
|---|
 | 1511 | +/* auth.c */  | 
|---|
 | 1512 | +static inline int ubifs_authenticated(const struct ubifs_info *c)  | 
|---|
 | 1513 | +{  | 
|---|
 | 1514 | +	return (IS_ENABLED(CONFIG_UBIFS_FS_AUTHENTICATION)) && c->authenticated;  | 
|---|
 | 1515 | +}  | 
|---|
 | 1516 | +  | 
|---|
 | 1517 | +struct shash_desc *__ubifs_hash_get_desc(const struct ubifs_info *c);  | 
|---|
 | 1518 | +static inline struct shash_desc *ubifs_hash_get_desc(const struct ubifs_info *c)  | 
|---|
 | 1519 | +{  | 
|---|
 | 1520 | +	return ubifs_authenticated(c) ? __ubifs_hash_get_desc(c) : NULL;  | 
|---|
 | 1521 | +}  | 
|---|
 | 1522 | +  | 
|---|
 | 1523 | +static inline int ubifs_shash_init(const struct ubifs_info *c,  | 
|---|
 | 1524 | +				   struct shash_desc *desc)  | 
|---|
 | 1525 | +{  | 
|---|
 | 1526 | +	if (ubifs_authenticated(c))  | 
|---|
 | 1527 | +		return crypto_shash_init(desc);  | 
|---|
 | 1528 | +	else  | 
|---|
 | 1529 | +		return 0;  | 
|---|
 | 1530 | +}  | 
|---|
 | 1531 | +  | 
|---|
 | 1532 | +static inline int ubifs_shash_update(const struct ubifs_info *c,  | 
|---|
 | 1533 | +				      struct shash_desc *desc, const void *buf,  | 
|---|
 | 1534 | +				      unsigned int len)  | 
|---|
 | 1535 | +{  | 
|---|
 | 1536 | +	int err = 0;  | 
|---|
 | 1537 | +  | 
|---|
 | 1538 | +	if (ubifs_authenticated(c)) {  | 
|---|
 | 1539 | +		err = crypto_shash_update(desc, buf, len);  | 
|---|
 | 1540 | +		if (err < 0)  | 
|---|
 | 1541 | +			return err;  | 
|---|
 | 1542 | +	}  | 
|---|
 | 1543 | +  | 
|---|
 | 1544 | +	return 0;  | 
|---|
 | 1545 | +}  | 
|---|
 | 1546 | +  | 
|---|
 | 1547 | +static inline int ubifs_shash_final(const struct ubifs_info *c,  | 
|---|
 | 1548 | +				    struct shash_desc *desc, u8 *out)  | 
|---|
 | 1549 | +{  | 
|---|
 | 1550 | +	return ubifs_authenticated(c) ? crypto_shash_final(desc, out) : 0;  | 
|---|
 | 1551 | +}  | 
|---|
 | 1552 | +  | 
|---|
 | 1553 | +int __ubifs_node_calc_hash(const struct ubifs_info *c, const void *buf,  | 
|---|
 | 1554 | +			  u8 *hash);  | 
|---|
 | 1555 | +static inline int ubifs_node_calc_hash(const struct ubifs_info *c,  | 
|---|
 | 1556 | +					const void *buf, u8 *hash)  | 
|---|
 | 1557 | +{  | 
|---|
 | 1558 | +	if (ubifs_authenticated(c))  | 
|---|
 | 1559 | +		return __ubifs_node_calc_hash(c, buf, hash);  | 
|---|
 | 1560 | +	else  | 
|---|
 | 1561 | +		return 0;  | 
|---|
 | 1562 | +}  | 
|---|
 | 1563 | +  | 
|---|
 | 1564 | +int ubifs_prepare_auth_node(struct ubifs_info *c, void *node,  | 
|---|
 | 1565 | +			     struct shash_desc *inhash);  | 
|---|
 | 1566 | +  | 
|---|
 | 1567 | +/**  | 
|---|
 | 1568 | + * ubifs_check_hash - compare two hashes  | 
|---|
 | 1569 | + * @c: UBIFS file-system description object  | 
|---|
 | 1570 | + * @expected: first hash  | 
|---|
 | 1571 | + * @got: second hash  | 
|---|
 | 1572 | + *  | 
|---|
 | 1573 | + * Compare two hashes @expected and @got. Returns 0 when they are equal, a  | 
|---|
 | 1574 | + * negative error code otherwise.  | 
|---|
 | 1575 | + */  | 
|---|
 | 1576 | +static inline int ubifs_check_hash(const struct ubifs_info *c,  | 
|---|
 | 1577 | +				   const u8 *expected, const u8 *got)  | 
|---|
 | 1578 | +{  | 
|---|
 | 1579 | +	return crypto_memneq(expected, got, c->hash_len);  | 
|---|
 | 1580 | +}  | 
|---|
 | 1581 | +  | 
|---|
 | 1582 | +/**  | 
|---|
 | 1583 | + * ubifs_check_hmac - compare two HMACs  | 
|---|
 | 1584 | + * @c: UBIFS file-system description object  | 
|---|
 | 1585 | + * @expected: first HMAC  | 
|---|
 | 1586 | + * @got: second HMAC  | 
|---|
 | 1587 | + *  | 
|---|
 | 1588 | + * Compare two hashes @expected and @got. Returns 0 when they are equal, a  | 
|---|
 | 1589 | + * negative error code otherwise.  | 
|---|
 | 1590 | + */  | 
|---|
 | 1591 | +static inline int ubifs_check_hmac(const struct ubifs_info *c,  | 
|---|
 | 1592 | +				   const u8 *expected, const u8 *got)  | 
|---|
 | 1593 | +{  | 
|---|
 | 1594 | +	return crypto_memneq(expected, got, c->hmac_desc_len);  | 
|---|
 | 1595 | +}  | 
|---|
 | 1596 | +  | 
|---|
 | 1597 | +#ifdef CONFIG_UBIFS_FS_AUTHENTICATION  | 
|---|
 | 1598 | +void ubifs_bad_hash(const struct ubifs_info *c, const void *node,  | 
|---|
 | 1599 | +		    const u8 *hash, int lnum, int offs);  | 
|---|
 | 1600 | +#else  | 
|---|
 | 1601 | +static inline void ubifs_bad_hash(const struct ubifs_info *c, const void *node,  | 
|---|
 | 1602 | +				  const u8 *hash, int lnum, int offs) {};  | 
|---|
 | 1603 | +#endif  | 
|---|
 | 1604 | +  | 
|---|
 | 1605 | +int __ubifs_node_check_hash(const struct ubifs_info *c, const void *buf,  | 
|---|
 | 1606 | +			  const u8 *expected);  | 
|---|
 | 1607 | +static inline int ubifs_node_check_hash(const struct ubifs_info *c,  | 
|---|
 | 1608 | +					const void *buf, const u8 *expected)  | 
|---|
 | 1609 | +{  | 
|---|
 | 1610 | +	if (ubifs_authenticated(c))  | 
|---|
 | 1611 | +		return __ubifs_node_check_hash(c, buf, expected);  | 
|---|
 | 1612 | +	else  | 
|---|
 | 1613 | +		return 0;  | 
|---|
 | 1614 | +}  | 
|---|
 | 1615 | +  | 
|---|
 | 1616 | +int ubifs_init_authentication(struct ubifs_info *c);  | 
|---|
 | 1617 | +void __ubifs_exit_authentication(struct ubifs_info *c);  | 
|---|
 | 1618 | +static inline void ubifs_exit_authentication(struct ubifs_info *c)  | 
|---|
 | 1619 | +{  | 
|---|
 | 1620 | +	if (ubifs_authenticated(c))  | 
|---|
 | 1621 | +		__ubifs_exit_authentication(c);  | 
|---|
 | 1622 | +}  | 
|---|
 | 1623 | +  | 
|---|
 | 1624 | +/**  | 
|---|
 | 1625 | + * ubifs_branch_hash - returns a pointer to the hash of a branch  | 
|---|
 | 1626 | + * @c: UBIFS file-system description object  | 
|---|
 | 1627 | + * @br: branch to get the hash from  | 
|---|
 | 1628 | + *  | 
|---|
 | 1629 | + * This returns a pointer to the hash of a branch. Since the key already is a  | 
|---|
 | 1630 | + * dynamically sized object we cannot use a struct member here.  | 
|---|
 | 1631 | + */  | 
|---|
 | 1632 | +static inline u8 *ubifs_branch_hash(struct ubifs_info *c,  | 
|---|
 | 1633 | +				    struct ubifs_branch *br)  | 
|---|
 | 1634 | +{  | 
|---|
 | 1635 | +	return (void *)br + sizeof(*br) + c->key_len;  | 
|---|
 | 1636 | +}  | 
|---|
 | 1637 | +  | 
|---|
 | 1638 | +/**  | 
|---|
 | 1639 | + * ubifs_copy_hash - copy a hash  | 
|---|
 | 1640 | + * @c: UBIFS file-system description object  | 
|---|
 | 1641 | + * @from: source hash  | 
|---|
 | 1642 | + * @to: destination hash  | 
|---|
 | 1643 | + *  | 
|---|
 | 1644 | + * With authentication this copies a hash, otherwise does nothing.  | 
|---|
 | 1645 | + */  | 
|---|
 | 1646 | +static inline void ubifs_copy_hash(const struct ubifs_info *c, const u8 *from,  | 
|---|
 | 1647 | +				   u8 *to)  | 
|---|
 | 1648 | +{  | 
|---|
 | 1649 | +	if (ubifs_authenticated(c))  | 
|---|
 | 1650 | +		memcpy(to, from, c->hash_len);  | 
|---|
 | 1651 | +}  | 
|---|
 | 1652 | +  | 
|---|
 | 1653 | +int __ubifs_node_insert_hmac(const struct ubifs_info *c, void *buf,  | 
|---|
 | 1654 | +			      int len, int ofs_hmac);  | 
|---|
 | 1655 | +static inline int ubifs_node_insert_hmac(const struct ubifs_info *c, void *buf,  | 
|---|
 | 1656 | +					  int len, int ofs_hmac)  | 
|---|
 | 1657 | +{  | 
|---|
 | 1658 | +	if (ubifs_authenticated(c))  | 
|---|
 | 1659 | +		return __ubifs_node_insert_hmac(c, buf, len, ofs_hmac);  | 
|---|
 | 1660 | +	else  | 
|---|
 | 1661 | +		return 0;  | 
|---|
 | 1662 | +}  | 
|---|
 | 1663 | +  | 
|---|
 | 1664 | +int __ubifs_node_verify_hmac(const struct ubifs_info *c, const void *buf,  | 
|---|
 | 1665 | +			     int len, int ofs_hmac);  | 
|---|
 | 1666 | +static inline int ubifs_node_verify_hmac(const struct ubifs_info *c,  | 
|---|
 | 1667 | +					 const void *buf, int len, int ofs_hmac)  | 
|---|
 | 1668 | +{  | 
|---|
 | 1669 | +	if (ubifs_authenticated(c))  | 
|---|
 | 1670 | +		return __ubifs_node_verify_hmac(c, buf, len, ofs_hmac);  | 
|---|
 | 1671 | +	else  | 
|---|
 | 1672 | +		return 0;  | 
|---|
 | 1673 | +}  | 
|---|
 | 1674 | +  | 
|---|
 | 1675 | +/**  | 
|---|
 | 1676 | + * ubifs_auth_node_sz - returns the size of an authentication node  | 
|---|
 | 1677 | + * @c: UBIFS file-system description object  | 
|---|
 | 1678 | + *  | 
|---|
 | 1679 | + * This function returns the size of an authentication node which can  | 
|---|
 | 1680 | + * be 0 for unauthenticated filesystems or the real size of an auth node  | 
|---|
 | 1681 | + * authentication is enabled.  | 
|---|
 | 1682 | + */  | 
|---|
 | 1683 | +static inline int ubifs_auth_node_sz(const struct ubifs_info *c)  | 
|---|
 | 1684 | +{  | 
|---|
 | 1685 | +	if (ubifs_authenticated(c))  | 
|---|
 | 1686 | +		return sizeof(struct ubifs_auth_node) + c->hmac_desc_len;  | 
|---|
 | 1687 | +	else  | 
|---|
 | 1688 | +		return 0;  | 
|---|
 | 1689 | +}  | 
|---|
 | 1690 | +int ubifs_sb_verify_signature(struct ubifs_info *c,  | 
|---|
 | 1691 | +			      const struct ubifs_sb_node *sup);  | 
|---|
 | 1692 | +bool ubifs_hmac_zero(struct ubifs_info *c, const u8 *hmac);  | 
|---|
 | 1693 | +  | 
|---|
 | 1694 | +int ubifs_hmac_wkm(struct ubifs_info *c, u8 *hmac);  | 
|---|
 | 1695 | +  | 
|---|
 | 1696 | +int __ubifs_shash_copy_state(const struct ubifs_info *c, struct shash_desc *src,  | 
|---|
 | 1697 | +			     struct shash_desc *target);  | 
|---|
 | 1698 | +static inline int ubifs_shash_copy_state(const struct ubifs_info *c,  | 
|---|
 | 1699 | +					   struct shash_desc *src,  | 
|---|
 | 1700 | +					   struct shash_desc *target)  | 
|---|
 | 1701 | +{  | 
|---|
 | 1702 | +	if (ubifs_authenticated(c))  | 
|---|
 | 1703 | +		return __ubifs_shash_copy_state(c, src, target);  | 
|---|
 | 1704 | +	else  | 
|---|
 | 1705 | +		return 0;  | 
|---|
 | 1706 | +}  | 
|---|
| 1472 | 1707 |   | 
|---|
| 1473 | 1708 |  /* io.c */ | 
|---|
| 1474 | 1709 |  void ubifs_ro_mode(struct ubifs_info *c, int err); | 
|---|
| .. | .. | 
|---|
| 1489 | 1724 |  			 int lnum, int offs); | 
|---|
| 1490 | 1725 |  int ubifs_write_node(struct ubifs_info *c, void *node, int len, int lnum, | 
|---|
| 1491 | 1726 |  		     int offs); | 
|---|
 | 1727 | +int ubifs_write_node_hmac(struct ubifs_info *c, void *buf, int len, int lnum,  | 
|---|
 | 1728 | +			  int offs, int hmac_offs);  | 
|---|
| 1492 | 1729 |  int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, | 
|---|
| 1493 | 1730 |  		     int offs, int quiet, int must_chk_crc); | 
|---|
 | 1731 | +void ubifs_init_node(struct ubifs_info *c, void *buf, int len, int pad);  | 
|---|
 | 1732 | +void ubifs_crc_node(struct ubifs_info *c, void *buf, int len);  | 
|---|
| 1494 | 1733 |  void ubifs_prepare_node(struct ubifs_info *c, void *buf, int len, int pad); | 
|---|
 | 1734 | +int ubifs_prepare_node_hmac(struct ubifs_info *c, void *node, int len,  | 
|---|
 | 1735 | +			    int hmac_offs, int pad);  | 
|---|
| 1495 | 1736 |  void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last); | 
|---|
| 1496 | 1737 |  int ubifs_io_init(struct ubifs_info *c); | 
|---|
| 1497 | 1738 |  void ubifs_pad(const struct ubifs_info *c, void *buf, int pad); | 
|---|
| .. | .. | 
|---|
| 1591 | 1832 |  int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key, | 
|---|
| 1592 | 1833 |  		     void *node, int *lnum, int *offs); | 
|---|
| 1593 | 1834 |  int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, | 
|---|
| 1594 |  | -		  int offs, int len);  | 
|---|
 | 1835 | +		  int offs, int len, const u8 *hash);  | 
|---|
| 1595 | 1836 |  int ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key, | 
|---|
| 1596 | 1837 |  		      int old_lnum, int old_offs, int lnum, int offs, int len); | 
|---|
| 1597 | 1838 |  int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, | 
|---|
| 1598 |  | -		     int lnum, int offs, int len, const struct fscrypt_name *nm);  | 
|---|
 | 1839 | +		     int lnum, int offs, int len, const u8 *hash,  | 
|---|
 | 1840 | +		     const struct fscrypt_name *nm);  | 
|---|
| 1599 | 1841 |  int ubifs_tnc_remove(struct ubifs_info *c, const union ubifs_key *key); | 
|---|
| 1600 | 1842 |  int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, | 
|---|
| 1601 | 1843 |  			const struct fscrypt_name *nm); | 
|---|
| .. | .. | 
|---|
| 1658 | 1900 |  void ubifs_wait_for_commit(struct ubifs_info *c); | 
|---|
| 1659 | 1901 |   | 
|---|
| 1660 | 1902 |  /* master.c */ | 
|---|
 | 1903 | +int ubifs_compare_master_node(struct ubifs_info *c, void *m1, void *m2);  | 
|---|
| 1661 | 1904 |  int ubifs_read_master(struct ubifs_info *c); | 
|---|
| 1662 | 1905 |  int ubifs_write_master(struct ubifs_info *c); | 
|---|
| 1663 | 1906 |   | 
|---|
| 1664 | 1907 |  /* sb.c */ | 
|---|
| 1665 | 1908 |  int ubifs_read_superblock(struct ubifs_info *c); | 
|---|
| 1666 |  | -struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c);  | 
|---|
| 1667 | 1909 |  int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup); | 
|---|
| 1668 | 1910 |  int ubifs_fixup_free_space(struct ubifs_info *c); | 
|---|
| 1669 | 1911 |  int ubifs_enable_encryption(struct ubifs_info *c); | 
|---|
| .. | .. | 
|---|
| 1692 | 1934 |  /* lpt.c */ | 
|---|
| 1693 | 1935 |  int ubifs_calc_lpt_geom(struct ubifs_info *c); | 
|---|
| 1694 | 1936 |  int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, | 
|---|
| 1695 |  | -			  int *lpt_lebs, int *big_lpt);  | 
|---|
 | 1937 | +			  int *lpt_lebs, int *big_lpt, u8 *hash);  | 
|---|
| 1696 | 1938 |  int ubifs_lpt_init(struct ubifs_info *c, int rd, int wr); | 
|---|
| 1697 | 1939 |  struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum); | 
|---|
| 1698 | 1940 |  struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum); | 
|---|
| .. | .. | 
|---|
| 1711 | 1953 |  				    struct ubifs_nnode *parent, int iip); | 
|---|
| 1712 | 1954 |  struct ubifs_nnode *ubifs_get_nnode(struct ubifs_info *c, | 
|---|
| 1713 | 1955 |  				    struct ubifs_nnode *parent, int iip); | 
|---|
 | 1956 | +struct ubifs_pnode *ubifs_pnode_lookup(struct ubifs_info *c, int i);  | 
|---|
| 1714 | 1957 |  int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip); | 
|---|
| 1715 | 1958 |  void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty); | 
|---|
| 1716 | 1959 |  void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode); | 
|---|
| .. | .. | 
|---|
| 1719 | 1962 |  /* Needed only in debugging code in lpt_commit.c */ | 
|---|
| 1720 | 1963 |  int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf, | 
|---|
| 1721 | 1964 |  		       struct ubifs_nnode *nnode); | 
|---|
 | 1965 | +int ubifs_lpt_calc_hash(struct ubifs_info *c, u8 *hash);  | 
|---|
| 1722 | 1966 |   | 
|---|
| 1723 | 1967 |  /* lpt_commit.c */ | 
|---|
| 1724 | 1968 |  int ubifs_lpt_start_commit(struct ubifs_info *c); | 
|---|
| .. | .. | 
|---|
| 1753 | 1997 |  /* file.c */ | 
|---|
| 1754 | 1998 |  int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync); | 
|---|
| 1755 | 1999 |  int ubifs_setattr(struct dentry *dentry, struct iattr *attr); | 
|---|
| 1756 |  | -#ifdef CONFIG_UBIFS_ATIME_SUPPORT  | 
|---|
| 1757 | 2000 |  int ubifs_update_time(struct inode *inode, struct timespec64 *time, int flags); | 
|---|
| 1758 |  | -#endif  | 
|---|
| 1759 | 2001 |   | 
|---|
| 1760 | 2002 |  /* dir.c */ | 
|---|
| 1761 | 2003 |  struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir, | 
|---|
| .. | .. | 
|---|
| 1774 | 2016 |   | 
|---|
| 1775 | 2017 |  #ifdef CONFIG_UBIFS_FS_XATTR | 
|---|
| 1776 | 2018 |  void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum); | 
|---|
 | 2019 | +int ubifs_purge_xattrs(struct inode *host);  | 
|---|
| 1777 | 2020 |  #else | 
|---|
| 1778 | 2021 |  static inline void ubifs_evict_xattr_inode(struct ubifs_info *c, | 
|---|
| 1779 | 2022 |  					   ino_t xattr_inum) { } | 
|---|
 | 2023 | +static inline int ubifs_purge_xattrs(struct inode *host)  | 
|---|
 | 2024 | +{  | 
|---|
 | 2025 | +	return 0;  | 
|---|
 | 2026 | +}  | 
|---|
| 1780 | 2027 |  #endif | 
|---|
| 1781 | 2028 |   | 
|---|
| 1782 | 2029 |  #ifdef CONFIG_UBIFS_FS_SECURITY | 
|---|
| .. | .. | 
|---|
| 1806 | 2053 |  int ubifs_rcvry_gc_commit(struct ubifs_info *c); | 
|---|
| 1807 | 2054 |  int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key, | 
|---|
| 1808 | 2055 |  			     int deletion, loff_t new_size); | 
|---|
| 1809 |  | -int ubifs_recover_size(struct ubifs_info *c);  | 
|---|
 | 2056 | +int ubifs_recover_size(struct ubifs_info *c, bool in_place);  | 
|---|
| 1810 | 2057 |  void ubifs_destroy_size_tree(struct ubifs_info *c); | 
|---|
| 1811 | 2058 |   | 
|---|
| 1812 | 2059 |  /* ioctl.c */ | 
|---|
| .. | .. | 
|---|
| 1855 | 2102 |  #endif | 
|---|
| 1856 | 2103 |   | 
|---|
| 1857 | 2104 |  extern const struct fscrypt_operations ubifs_crypt_operations; | 
|---|
| 1858 |  | -  | 
|---|
| 1859 |  | -static inline bool ubifs_crypt_is_encrypted(const struct inode *inode)  | 
|---|
| 1860 |  | -{  | 
|---|
| 1861 |  | -	const struct ubifs_inode *ui = ubifs_inode(inode);  | 
|---|
| 1862 |  | -  | 
|---|
| 1863 |  | -	return ui->flags & UBIFS_CRYPT_FL;  | 
|---|
| 1864 |  | -}  | 
|---|
| 1865 | 2105 |   | 
|---|
| 1866 | 2106 |  /* Normal UBIFS messages */ | 
|---|
| 1867 | 2107 |  __printf(2, 3) | 
|---|