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) ...@@ -1101,10 +1101,10 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
ubi_wl_close(ubi); ubi_wl_close(ubi);
ubi_free_internal_volumes(ubi); ubi_free_internal_volumes(ubi);
vfree(ubi->vtbl); vfree(ubi->vtbl);
put_mtd_device(ubi->mtd);
vfree(ubi->peb_buf); vfree(ubi->peb_buf);
vfree(ubi->fm_buf); vfree(ubi->fm_buf);
ubi_msg(ubi, "mtd%d is detached", ubi->mtd->index); ubi_msg(ubi, "mtd%d is detached", ubi->mtd->index);
put_mtd_device(ubi->mtd);
put_device(&ubi->dev); put_device(&ubi->dev);
return 0; return 0;
} }
......
...@@ -227,9 +227,9 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode) ...@@ -227,9 +227,9 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
out_free: out_free:
kfree(desc); kfree(desc);
out_put_ubi: out_put_ubi:
ubi_put_device(ubi);
ubi_err(ubi, "cannot open device %d, volume %d, error %d", ubi_err(ubi, "cannot open device %d, volume %d, error %d",
ubi_num, vol_id, err); ubi_num, vol_id, err);
ubi_put_device(ubi);
return ERR_PTR(err); return ERR_PTR(err);
} }
EXPORT_SYMBOL_GPL(ubi_open_volume); EXPORT_SYMBOL_GPL(ubi_open_volume);
......
...@@ -12,9 +12,10 @@ config UBIFS_FS ...@@ -12,9 +12,10 @@ config UBIFS_FS
help help
UBIFS is a file system for flash devices which works on top of UBI. UBIFS is a file system for flash devices which works on top of UBI.
if UBIFS_FS
config UBIFS_FS_ADVANCED_COMPR config UBIFS_FS_ADVANCED_COMPR
bool "Advanced compression options" bool "Advanced compression options"
depends on UBIFS_FS
help help
This option allows to explicitly choose which compressions, if any, This option allows to explicitly choose which compressions, if any,
are enabled in UBIFS. Removing compressors means inability to read are enabled in UBIFS. Removing compressors means inability to read
...@@ -24,7 +25,6 @@ config UBIFS_FS_ADVANCED_COMPR ...@@ -24,7 +25,6 @@ config UBIFS_FS_ADVANCED_COMPR
config UBIFS_FS_LZO config UBIFS_FS_LZO
bool "LZO compression support" if UBIFS_FS_ADVANCED_COMPR bool "LZO compression support" if UBIFS_FS_ADVANCED_COMPR
depends on UBIFS_FS
default y default y
help help
LZO compressor is generally faster than zlib but compresses worse. LZO compressor is generally faster than zlib but compresses worse.
...@@ -32,14 +32,12 @@ config UBIFS_FS_LZO ...@@ -32,14 +32,12 @@ config UBIFS_FS_LZO
config UBIFS_FS_ZLIB config UBIFS_FS_ZLIB
bool "ZLIB compression support" if UBIFS_FS_ADVANCED_COMPR bool "ZLIB compression support" if UBIFS_FS_ADVANCED_COMPR
depends on UBIFS_FS
default y default y
help help
Zlib compresses better than LZO but it is slower. Say 'Y' if unsure. Zlib compresses better than LZO but it is slower. Say 'Y' if unsure.
config UBIFS_ATIME_SUPPORT config UBIFS_ATIME_SUPPORT
bool "Access time support" if UBIFS_FS bool "Access time support"
depends on UBIFS_FS
default n default n
help help
Originally UBIFS did not support atime, because it looked like a bad idea due Originally UBIFS did not support atime, because it looked like a bad idea due
...@@ -54,7 +52,6 @@ config UBIFS_ATIME_SUPPORT ...@@ -54,7 +52,6 @@ config UBIFS_ATIME_SUPPORT
config UBIFS_FS_XATTR config UBIFS_FS_XATTR
bool "UBIFS XATTR support" bool "UBIFS XATTR support"
depends on UBIFS_FS
default y default y
help help
Saying Y here includes support for extended attributes (xattrs). Saying Y here includes support for extended attributes (xattrs).
...@@ -65,7 +62,7 @@ config UBIFS_FS_XATTR ...@@ -65,7 +62,7 @@ config UBIFS_FS_XATTR
config UBIFS_FS_ENCRYPTION config UBIFS_FS_ENCRYPTION
bool "UBIFS Encryption" bool "UBIFS Encryption"
depends on UBIFS_FS && UBIFS_FS_XATTR && BLOCK depends on UBIFS_FS_XATTR && BLOCK
select FS_ENCRYPTION select FS_ENCRYPTION
default n default n
help help
...@@ -76,7 +73,7 @@ config UBIFS_FS_ENCRYPTION ...@@ -76,7 +73,7 @@ config UBIFS_FS_ENCRYPTION
config UBIFS_FS_SECURITY config UBIFS_FS_SECURITY
bool "UBIFS Security Labels" bool "UBIFS Security Labels"
depends on UBIFS_FS && UBIFS_FS_XATTR depends on UBIFS_FS_XATTR
default y default y
help help
Security labels provide an access control facility to support Linux Security labels provide an access control facility to support Linux
...@@ -89,6 +86,7 @@ config UBIFS_FS_SECURITY ...@@ -89,6 +86,7 @@ config UBIFS_FS_SECURITY
config UBIFS_FS_AUTHENTICATION config UBIFS_FS_AUTHENTICATION
bool "UBIFS authentication support" bool "UBIFS authentication support"
depends on KEYS
select CRYPTO_HMAC select CRYPTO_HMAC
help help
Enable authentication support for UBIFS. This feature offers protection Enable authentication support for UBIFS. This feature offers protection
...@@ -96,3 +94,5 @@ config UBIFS_FS_AUTHENTICATION ...@@ -96,3 +94,5 @@ config UBIFS_FS_AUTHENTICATION
If you say yes here you should also select a hashing algorithm such as If you say yes here you should also select a hashing algorithm such as
sha256, these are not selected automatically since there are many sha256, these are not selected automatically since there are many
different options. different options.
endif # UBIFS_FS
...@@ -1675,6 +1675,12 @@ int ubifs_lpt_calc_hash(struct ubifs_info *c, u8 *hash) ...@@ -1675,6 +1675,12 @@ int ubifs_lpt_calc_hash(struct ubifs_info *c, u8 *hash)
if (!ubifs_authenticated(c)) if (!ubifs_authenticated(c))
return 0; return 0;
if (!c->nroot) {
err = ubifs_read_nnode(c, NULL, 0);
if (err)
return err;
}
desc = ubifs_hash_get_desc(c); desc = ubifs_hash_get_desc(c);
if (IS_ERR(desc)) if (IS_ERR(desc))
return PTR_ERR(desc); return PTR_ERR(desc);
...@@ -1685,12 +1691,6 @@ int ubifs_lpt_calc_hash(struct ubifs_info *c, u8 *hash) ...@@ -1685,12 +1691,6 @@ int ubifs_lpt_calc_hash(struct ubifs_info *c, u8 *hash)
goto out; goto out;
} }
if (!c->nroot) {
err = ubifs_read_nnode(c, NULL, 0);
if (err)
return err;
}
cnode = (struct ubifs_cnode *)c->nroot; cnode = (struct ubifs_cnode *)c->nroot;
while (cnode) { while (cnode) {
......
...@@ -212,6 +212,38 @@ static int trun_remove_range(struct ubifs_info *c, struct replay_entry *r) ...@@ -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); 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. * apply_replay_entry - apply a replay entry to the TNC.
* @c: UBIFS file-system description object * @c: UBIFS file-system description object
...@@ -239,6 +271,11 @@ static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r) ...@@ -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); ino_t inum = key_inum(c, &r->key);
if (inode_still_linked(c, r)) {
err = 0;
break;
}
err = ubifs_tnc_remove_ino(c, inum); err = ubifs_tnc_remove_ino(c, inum);
break; break;
} }
...@@ -533,6 +570,28 @@ static int is_last_bud(struct ubifs_info *c, struct ubifs_bud *bud) ...@@ -533,6 +570,28 @@ static int is_last_bud(struct ubifs_info *c, struct ubifs_bud *bud)
return data == 0xFFFFFFFF; 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 * authenticate_sleb - authenticate one scan LEB
* @c: UBIFS file-system description object * @c: UBIFS file-system description object
...@@ -574,21 +633,12 @@ static int authenticate_sleb(struct ubifs_info *c, struct ubifs_scan_leb *sleb, ...@@ -574,21 +633,12 @@ static int authenticate_sleb(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
if (snod->type == UBIFS_AUTH_NODE) { if (snod->type == UBIFS_AUTH_NODE) {
struct ubifs_auth_node *auth = snod->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 = authenticate_sleb_hash(c, log_hash, hash);
err = crypto_shash_final(hash_desc, hash);
if (err) if (err)
goto out; goto out;
hmac_desc->tfm = c->hmac_tfm; err = authenticate_sleb_hmac(c, hash, hmac);
hmac_desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
err = crypto_shash_digest(hmac_desc, hash, c->hash_len,
hmac);
if (err) if (err)
goto out; goto out;
......
...@@ -63,6 +63,17 @@ ...@@ -63,6 +63,17 @@
/* Default time granularity in nanoseconds */ /* Default time granularity in nanoseconds */
#define DEFAULT_TIME_GRAN 1000000000 #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. * create_default_filesystem - format empty UBI volume.
* @c: UBIFS file-system description object * @c: UBIFS file-system description object
...@@ -207,7 +218,7 @@ static int create_default_filesystem(struct ubifs_info *c) ...@@ -207,7 +218,7 @@ static int create_default_filesystem(struct ubifs_info *c)
if (c->mount_opts.override_compr) if (c->mount_opts.override_compr)
sup->default_compr = cpu_to_le16(c->mount_opts.compr_type); sup->default_compr = cpu_to_le16(c->mount_opts.compr_type);
else 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); 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