[PATCH 17/24] ubifs: Implement encrypted filenames
Signed-off-by: Richard WeinbergerSigned-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
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, )) {