[PATCH 17/24] ubifs: Implement encrypted filenames

2016-12-01 Thread Richard Weinberger
Signed-off-by: Richard Weinberger 
Signed-off-by: David Gstir 
---
 fs/ubifs/debug.c   |  14 +--
 fs/ubifs/dir.c | 323 +++--
 fs/ubifs/journal.c | 123 ++--
 fs/ubifs/key.h |  19 ++--
 fs/ubifs/replay.c  |   8 +-
 fs/ubifs/tnc.c |  54 -
 fs/ubifs/ubifs.h   |  24 ++--
 fs/ubifs/xattr.c   |  46 
 8 files changed, 414 insertions(+), 197 deletions(-)

diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 69e287e20732..1e712a364680 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -233,7 +233,7 @@ static void dump_ch(const struct ubifs_ch *ch)
 void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
 {
const struct ubifs_inode *ui = ubifs_inode(inode);
-   struct qstr nm = { .name = NULL };
+   struct fscrypt_name nm = {0};
union ubifs_key key;
struct ubifs_dent_node *dent, *pdent = NULL;
int count = 2;
@@ -289,8 +289,8 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct 
inode *inode)
pr_err("\t%d: %s (%s)\n",
   count++, dent->name, get_dent_type(dent->type));
 
-   nm.name = dent->name;
-   nm.len = le16_to_cpu(dent->nlen);
+   fname_name() = dent->name;
+   fname_len() = le16_to_cpu(dent->nlen);
kfree(pdent);
pdent = dent;
key_read(c, >key, );
@@ -1107,7 +1107,7 @@ int dbg_check_dir(struct ubifs_info *c, const struct 
inode *dir)
unsigned int nlink = 2;
union ubifs_key key;
struct ubifs_dent_node *dent, *pdent = NULL;
-   struct qstr nm = { .name = NULL };
+   struct fscrypt_name nm = {0};
loff_t size = UBIFS_INO_NODE_SZ;
 
if (!dbg_is_chk_gen(c))
@@ -1128,9 +1128,9 @@ int dbg_check_dir(struct ubifs_info *c, const struct 
inode *dir)
return err;
}
 
-   nm.name = dent->name;
-   nm.len = le16_to_cpu(dent->nlen);
-   size += CALC_DENT_SIZE(nm.len);
+   fname_name() = dent->name;
+   fname_len() = le16_to_cpu(dent->nlen);
+   size += CALC_DENT_SIZE(fname_len());
if (dent->type == UBIFS_ITYPE_DIR)
nlink += 1;
kfree(pdent);
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 9976a709b875..7d1bd4b28140 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -196,13 +196,13 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, 
struct inode *dir,
 
 static int dbg_check_name(const struct ubifs_info *c,
  const struct ubifs_dent_node *dent,
- const struct qstr *nm)
+ const struct fscrypt_name *nm)
 {
if (!dbg_is_chk_gen(c))
return 0;
-   if (le16_to_cpu(dent->nlen) != nm->len)
+   if (le16_to_cpu(dent->nlen) != fname_len(nm))
return -EINVAL;
-   if (memcmp(dent->name, nm->name, nm->len))
+   if (memcmp(dent->name, fname_name(nm), fname_len(nm)))
return -EINVAL;
return 0;
 }
@@ -215,6 +215,7 @@ static struct dentry *ubifs_lookup(struct inode *dir, 
struct dentry *dentry,
struct inode *inode = NULL;
struct ubifs_dent_node *dent;
struct ubifs_info *c = dir->i_sb->s_fs_info;
+   struct fscrypt_name nm;
 
dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino);
 
@@ -233,27 +234,42 @@ static struct dentry *ubifs_lookup(struct inode *dir, 
struct dentry *dentry,
return ERR_PTR(err);
}
 
-   if (dentry->d_name.len > UBIFS_MAX_NLEN)
-   return ERR_PTR(-ENAMETOOLONG);
+   err = fscrypt_setup_filename(dir, >d_name, 1, );
+   if (err)
+   return ERR_PTR(err);
+
+   if (fname_len() > UBIFS_MAX_NLEN) {
+   err = -ENAMETOOLONG;
+   goto out_fname;
+   }
 
dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS);
-   if (!dent)
-   return ERR_PTR(-ENOMEM);
+   if (!dent) {
+   err = -ENOMEM;
+   goto out_fname;
+   }
 
-   dent_key_init(c, , dir->i_ino, >d_name);
+   if (nm.hash) {
+   ubifs_assert(fname_len() == 0);
+   ubifs_assert(fname_name() == NULL);
+   dent_key_init_hash(c, , dir->i_ino, nm.hash);
+   err = ubifs_tnc_lookup(c, , dent);
+   } else {
+   dent_key_init(c, , dir->i_ino, );
+   err = ubifs_tnc_lookup_nm(c, , dent, );
+   }
 
-   err = ubifs_tnc_lookup_nm(c, , dent, >d_name);
if (err) {
if (err == -ENOENT) {
dbg_gen("not found");
goto done;
}
-   goto out;
+   goto out_dent;
}
 
-   if (dbg_check_name(c, dent, >d_name)) {
+   if 

[PATCH 17/24] ubifs: Implement encrypted filenames

2016-12-01 Thread Richard Weinberger
Signed-off-by: Richard Weinberger 
Signed-off-by: David Gstir 
---
 fs/ubifs/debug.c   |  14 +--
 fs/ubifs/dir.c | 323 +++--
 fs/ubifs/journal.c | 123 ++--
 fs/ubifs/key.h |  19 ++--
 fs/ubifs/replay.c  |   8 +-
 fs/ubifs/tnc.c |  54 -
 fs/ubifs/ubifs.h   |  24 ++--
 fs/ubifs/xattr.c   |  46 
 8 files changed, 414 insertions(+), 197 deletions(-)

diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 69e287e20732..1e712a364680 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -233,7 +233,7 @@ static void dump_ch(const struct ubifs_ch *ch)
 void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
 {
const struct ubifs_inode *ui = ubifs_inode(inode);
-   struct qstr nm = { .name = NULL };
+   struct fscrypt_name nm = {0};
union ubifs_key key;
struct ubifs_dent_node *dent, *pdent = NULL;
int count = 2;
@@ -289,8 +289,8 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct 
inode *inode)
pr_err("\t%d: %s (%s)\n",
   count++, dent->name, get_dent_type(dent->type));
 
-   nm.name = dent->name;
-   nm.len = le16_to_cpu(dent->nlen);
+   fname_name() = dent->name;
+   fname_len() = le16_to_cpu(dent->nlen);
kfree(pdent);
pdent = dent;
key_read(c, >key, );
@@ -1107,7 +1107,7 @@ int dbg_check_dir(struct ubifs_info *c, const struct 
inode *dir)
unsigned int nlink = 2;
union ubifs_key key;
struct ubifs_dent_node *dent, *pdent = NULL;
-   struct qstr nm = { .name = NULL };
+   struct fscrypt_name nm = {0};
loff_t size = UBIFS_INO_NODE_SZ;
 
if (!dbg_is_chk_gen(c))
@@ -1128,9 +1128,9 @@ int dbg_check_dir(struct ubifs_info *c, const struct 
inode *dir)
return err;
}
 
-   nm.name = dent->name;
-   nm.len = le16_to_cpu(dent->nlen);
-   size += CALC_DENT_SIZE(nm.len);
+   fname_name() = dent->name;
+   fname_len() = le16_to_cpu(dent->nlen);
+   size += CALC_DENT_SIZE(fname_len());
if (dent->type == UBIFS_ITYPE_DIR)
nlink += 1;
kfree(pdent);
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 9976a709b875..7d1bd4b28140 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -196,13 +196,13 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, 
struct inode *dir,
 
 static int dbg_check_name(const struct ubifs_info *c,
  const struct ubifs_dent_node *dent,
- const struct qstr *nm)
+ const struct fscrypt_name *nm)
 {
if (!dbg_is_chk_gen(c))
return 0;
-   if (le16_to_cpu(dent->nlen) != nm->len)
+   if (le16_to_cpu(dent->nlen) != fname_len(nm))
return -EINVAL;
-   if (memcmp(dent->name, nm->name, nm->len))
+   if (memcmp(dent->name, fname_name(nm), fname_len(nm)))
return -EINVAL;
return 0;
 }
@@ -215,6 +215,7 @@ static struct dentry *ubifs_lookup(struct inode *dir, 
struct dentry *dentry,
struct inode *inode = NULL;
struct ubifs_dent_node *dent;
struct ubifs_info *c = dir->i_sb->s_fs_info;
+   struct fscrypt_name nm;
 
dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino);
 
@@ -233,27 +234,42 @@ static struct dentry *ubifs_lookup(struct inode *dir, 
struct dentry *dentry,
return ERR_PTR(err);
}
 
-   if (dentry->d_name.len > UBIFS_MAX_NLEN)
-   return ERR_PTR(-ENAMETOOLONG);
+   err = fscrypt_setup_filename(dir, >d_name, 1, );
+   if (err)
+   return ERR_PTR(err);
+
+   if (fname_len() > UBIFS_MAX_NLEN) {
+   err = -ENAMETOOLONG;
+   goto out_fname;
+   }
 
dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS);
-   if (!dent)
-   return ERR_PTR(-ENOMEM);
+   if (!dent) {
+   err = -ENOMEM;
+   goto out_fname;
+   }
 
-   dent_key_init(c, , dir->i_ino, >d_name);
+   if (nm.hash) {
+   ubifs_assert(fname_len() == 0);
+   ubifs_assert(fname_name() == NULL);
+   dent_key_init_hash(c, , dir->i_ino, nm.hash);
+   err = ubifs_tnc_lookup(c, , dent);
+   } else {
+   dent_key_init(c, , dir->i_ino, );
+   err = ubifs_tnc_lookup_nm(c, , dent, );
+   }
 
-   err = ubifs_tnc_lookup_nm(c, , dent, >d_name);
if (err) {
if (err == -ENOENT) {
dbg_gen("not found");
goto done;
}
-   goto out;
+   goto out_dent;
}
 
-   if (dbg_check_name(c, dent, >d_name)) {
+   if (dbg_check_name(c, dent, )) {