ubifs: allow both hash and disk name to be provided in no-key names
authorEric Biggers <ebiggers@google.com>
Mon, 20 Jan 2020 22:32:00 +0000 (14:32 -0800)
committerEric Biggers <ebiggers@google.com>
Wed, 22 Jan 2020 22:49:56 +0000 (14:49 -0800)
In order to support a new dirhash method that is a secret-keyed hash
over the plaintext filenames (which will be used by encrypted+casefolded
directories on ext4 and f2fs), fscrypt will be switching to a new no-key
name format that always encodes the dirhash in the name.

UBIFS isn't happy with this because it has assertions that verify that
either the hash or the disk name is provided, not both.

Change it to use the disk name if one is provided, even if a hash is
available too; else use the hash.

Link: https://lore.kernel.org/r/20200120223201.241390-6-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
fs/ubifs/dir.c
fs/ubifs/journal.c
fs/ubifs/key.h

index 5f937226976a621c55c497155db5f5b0a0072ae5..ef85ec167a843635cf314d772021e2367f72d892 100644 (file)
@@ -225,9 +225,7 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
                goto done;
        }
 
-       if (nm.hash) {
-               ubifs_assert(c, fname_len(&nm) == 0);
-               ubifs_assert(c, fname_name(&nm) == NULL);
+       if (fname_name(&nm) == NULL) {
                if (nm.hash & ~UBIFS_S_KEY_HASH_MASK)
                        goto done; /* ENOENT */
                dent_key_init_hash(c, &key, dir->i_ino, nm.hash);
index a38e18d3ef1d70e90319ec25d987eafa8d49e1c1..3bf8b1fda9d7487d567258d2b907f3051683bc01 100644 (file)
@@ -588,7 +588,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
 
        if (!xent) {
                dent->ch.node_type = UBIFS_DENT_NODE;
-               if (nm->hash)
+               if (fname_name(nm) == NULL)
                        dent_key_init_hash(c, &dent_key, dir->i_ino, nm->hash);
                else
                        dent_key_init(c, &dent_key, dir->i_ino, nm);
@@ -646,7 +646,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
        ubifs_add_auth_dirt(c, lnum);
 
        if (deletion) {
-               if (nm->hash)
+               if (fname_name(nm) == NULL)
                        err = ubifs_tnc_remove_dh(c, &dent_key, nm->minor_hash);
                else
                        err = ubifs_tnc_remove_nm(c, &dent_key, nm);
index afa704ff5ca08613804aee44a9858cb896679d9c..8142d9d6fe5dab44829c0c91ea4429423babbfb1 100644 (file)
@@ -150,7 +150,6 @@ static inline void dent_key_init(const struct ubifs_info *c,
        uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
 
        ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
-       ubifs_assert(c, !nm->hash && !nm->minor_hash);
        key->u32[0] = inum;
        key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
 }