Commit f57b620a authored by Linus Torvalds's avatar Linus Torvalds

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
......@@ -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;
}
......
......@@ -227,9 +227,9 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
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);
......
......@@ -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
......@@ -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) {
......
......@@ -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;
......
......@@ -63,6 +63,17 @@
/* Default time granularity in nanoseconds */
#define DEFAULT_TIME_GRAN 1000000000
static int get_default_compressor(struct ubifs_info *c)
{
if (ubifs_compr_present(c, UBIFS_COMPR_LZO))
return UBIFS_COMPR_LZO;
if (ubifs_compr_present(c, UBIFS_COMPR_ZLIB))
return UBIFS_COMPR_ZLIB;
return UBIFS_COMPR_NONE;
}
/**
* create_default_filesystem - format empty UBI volume.
* @c: UBIFS file-system description object
......@@ -207,7 +218,7 @@ static int create_default_filesystem(struct ubifs_info *c)
if (c->mount_opts.override_compr)
sup->default_compr = cpu_to_le16(c->mount_opts.compr_type);
else
sup->default_compr = cpu_to_le16(UBIFS_COMPR_LZO);
sup->default_compr = cpu_to_le16(get_default_compressor(c));
generate_random_uuid(sup->uuid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment