Commit f57b620a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'upstream-4.20-rc7' of git://git.infradead.org/linux-ubifs

Pull UBI/UBIFS fixes from Richard Weinberger:

 - Kconfig dependency fixes for our new auth feature

 - Fix for selecting the right compressor when creating a fs

 - Bugfix for a bug in UBIFS's O_TMPFILE implementation

 - Refcounting fixes for UBI

* tag 'upstream-4.20-rc7' of git://git.infradead.org/linux-ubifs:
  ubifs: Handle re-linking of inodes correctly while recovery
  ubi: Do not drop UBI device reference before using
  ubi: Put MTD device after it is not used
  ubifs: Fix default compression selection in ubifs
  ubifs: Fix memory leak on error condition
  ubifs: auth: Add CONFIG_KEYS dependency
  ubifs: CONFIG_UBIFS_FS_AUTHENTICATION should depend on UBIFS_FS
  ubifs: replay: Fix high stack usage
parents 1d51b4b1 e58725d5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1101,10 +1101,10 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
	ubi_wl_close(ubi);
	ubi_free_internal_volumes(ubi);
	vfree(ubi->vtbl);
	put_mtd_device(ubi->mtd);
	vfree(ubi->peb_buf);
	vfree(ubi->fm_buf);
	ubi_msg(ubi, "mtd%d is detached", ubi->mtd->index);
	put_mtd_device(ubi->mtd);
	put_device(&ubi->dev);
	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -227,9 +227,9 @@ out_unlock:
out_free:
	kfree(desc);
out_put_ubi:
	ubi_put_device(ubi);
	ubi_err(ubi, "cannot open device %d, volume %d, error %d",
		ubi_num, vol_id, err);
	ubi_put_device(ubi);
	return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(ubi_open_volume);
+8 −8
Original line number Diff line number Diff line
@@ -12,9 +12,10 @@ config UBIFS_FS
	help
	  UBIFS is a file system for flash devices which works on top of UBI.

if UBIFS_FS

config UBIFS_FS_ADVANCED_COMPR
	bool "Advanced compression options"
	depends on UBIFS_FS
	help
	  This option allows to explicitly choose which compressions, if any,
	  are enabled in UBIFS. Removing compressors means inability to read
@@ -24,7 +25,6 @@ config UBIFS_FS_ADVANCED_COMPR

config UBIFS_FS_LZO
	bool "LZO compression support" if UBIFS_FS_ADVANCED_COMPR
	depends on UBIFS_FS
	default y
	help
	   LZO compressor is generally faster than zlib but compresses worse.
@@ -32,14 +32,12 @@ config UBIFS_FS_LZO

config UBIFS_FS_ZLIB
	bool "ZLIB compression support" if UBIFS_FS_ADVANCED_COMPR
	depends on UBIFS_FS
	default y
	help
	  Zlib compresses better than LZO but it is slower. Say 'Y' if unsure.

config UBIFS_ATIME_SUPPORT
	bool "Access time support" if UBIFS_FS
	depends on UBIFS_FS
	bool "Access time support"
	default n
	help
	  Originally UBIFS did not support atime, because it looked like a bad idea due
@@ -54,7 +52,6 @@ config UBIFS_ATIME_SUPPORT

config UBIFS_FS_XATTR
	bool "UBIFS XATTR support"
	depends on UBIFS_FS
	default y
	help
	  Saying Y here includes support for extended attributes (xattrs).
@@ -65,7 +62,7 @@ config UBIFS_FS_XATTR

config UBIFS_FS_ENCRYPTION
	bool "UBIFS Encryption"
	depends on UBIFS_FS && UBIFS_FS_XATTR && BLOCK
	depends on UBIFS_FS_XATTR && BLOCK
	select FS_ENCRYPTION
	default n
	help
@@ -76,7 +73,7 @@ config UBIFS_FS_ENCRYPTION

config UBIFS_FS_SECURITY
	bool "UBIFS Security Labels"
	depends on UBIFS_FS && UBIFS_FS_XATTR
	depends on UBIFS_FS_XATTR
	default y
	help
	  Security labels provide an access control facility to support Linux
@@ -89,6 +86,7 @@ config UBIFS_FS_SECURITY

config UBIFS_FS_AUTHENTICATION
	bool "UBIFS authentication support"
	depends on KEYS
	select CRYPTO_HMAC
	help
	  Enable authentication support for UBIFS. This feature offers protection
@@ -96,3 +94,5 @@ config UBIFS_FS_AUTHENTICATION
	  If you say yes here you should also select a hashing algorithm such as
	  sha256, these are not selected automatically since there are many
	  different options.

endif # UBIFS_FS
+6 −6
Original line number Diff line number Diff line
@@ -1675,6 +1675,12 @@ int ubifs_lpt_calc_hash(struct ubifs_info *c, u8 *hash)
	if (!ubifs_authenticated(c))
		return 0;

	if (!c->nroot) {
		err = ubifs_read_nnode(c, NULL, 0);
		if (err)
			return err;
	}

	desc = ubifs_hash_get_desc(c);
	if (IS_ERR(desc))
		return PTR_ERR(desc);
@@ -1685,12 +1691,6 @@ int ubifs_lpt_calc_hash(struct ubifs_info *c, u8 *hash)
		goto out;
	}

	if (!c->nroot) {
		err = ubifs_read_nnode(c, NULL, 0);
		if (err)
			return err;
	}

	cnode = (struct ubifs_cnode *)c->nroot;

	while (cnode) {
+61 −11
Original line number Diff line number Diff line
@@ -212,6 +212,38 @@ static int trun_remove_range(struct ubifs_info *c, struct replay_entry *r)
	return ubifs_tnc_remove_range(c, &min_key, &max_key);
}

/**
 * inode_still_linked - check whether inode in question will be re-linked.
 * @c: UBIFS file-system description object
 * @rino: replay entry to test
 *
 * O_TMPFILE files can be re-linked, this means link count goes from 0 to 1.
 * This case needs special care, otherwise all references to the inode will
 * be removed upon the first replay entry of an inode with link count 0
 * is found.
 */
static bool inode_still_linked(struct ubifs_info *c, struct replay_entry *rino)
{
	struct replay_entry *r;

	ubifs_assert(c, rino->deletion);
	ubifs_assert(c, key_type(c, &rino->key) == UBIFS_INO_KEY);

	/*
	 * Find the most recent entry for the inode behind @rino and check
	 * whether it is a deletion.
	 */
	list_for_each_entry_reverse(r, &c->replay_list, list) {
		ubifs_assert(c, r->sqnum >= rino->sqnum);
		if (key_inum(c, &r->key) == key_inum(c, &rino->key))
			return r->deletion == 0;

	}

	ubifs_assert(c, 0);
	return false;
}

/**
 * apply_replay_entry - apply a replay entry to the TNC.
 * @c: UBIFS file-system description object
@@ -239,6 +271,11 @@ static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r)
			{
				ino_t inum = key_inum(c, &r->key);

				if (inode_still_linked(c, r)) {
					err = 0;
					break;
				}

				err = ubifs_tnc_remove_ino(c, inum);
				break;
			}
@@ -533,6 +570,28 @@ static int is_last_bud(struct ubifs_info *c, struct ubifs_bud *bud)
	return data == 0xFFFFFFFF;
}

/* authenticate_sleb_hash and authenticate_sleb_hmac are split out for stack usage */
static int authenticate_sleb_hash(struct ubifs_info *c, struct shash_desc *log_hash, u8 *hash)
{
	SHASH_DESC_ON_STACK(hash_desc, c->hash_tfm);

	hash_desc->tfm = c->hash_tfm;
	hash_desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;

	ubifs_shash_copy_state(c, log_hash, hash_desc);
	return crypto_shash_final(hash_desc, hash);
}

static int authenticate_sleb_hmac(struct ubifs_info *c, u8 *hash, u8 *hmac)
{
	SHASH_DESC_ON_STACK(hmac_desc, c->hmac_tfm);

	hmac_desc->tfm = c->hmac_tfm;
	hmac_desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;

	return crypto_shash_digest(hmac_desc, hash, c->hash_len, hmac);
}

/**
 * authenticate_sleb - authenticate one scan LEB
 * @c: UBIFS file-system description object
@@ -574,21 +633,12 @@ static int authenticate_sleb(struct ubifs_info *c, struct ubifs_scan_leb *sleb,

		if (snod->type == UBIFS_AUTH_NODE) {
			struct ubifs_auth_node *auth = snod->node;
			SHASH_DESC_ON_STACK(hash_desc, c->hash_tfm);
			SHASH_DESC_ON_STACK(hmac_desc, c->hmac_tfm);

			hash_desc->tfm = c->hash_tfm;
			hash_desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;

			ubifs_shash_copy_state(c, log_hash, hash_desc);
			err = crypto_shash_final(hash_desc, hash);
			err = authenticate_sleb_hash(c, log_hash, hash);
			if (err)
				goto out;

			hmac_desc->tfm = c->hmac_tfm;
			hmac_desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
			err = crypto_shash_digest(hmac_desc, hash, c->hash_len,
						  hmac);
			err = authenticate_sleb_hmac(c, hash, hmac);
			if (err)
				goto out;

Loading