ext4 crypto: teach ext4_htree_store_dirent() to store decrypted filenames
For encrypted directories, we need to pass in a separate parameter for the decrypted filename, since the directory entry contains the encrypted filename. Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
d5d0e8c720
commit
2f61830ae3
@ -382,10 +382,15 @@ void ext4_htree_free_dir_info(struct dir_private_info *p)
|
||||
|
||||
/*
|
||||
* Given a directory entry, enter it into the fname rb tree.
|
||||
*
|
||||
* When filename encryption is enabled, the dirent will hold the
|
||||
* encrypted filename, while the htree will hold decrypted filename.
|
||||
* The decrypted filename is passed in via ent_name. parameter.
|
||||
*/
|
||||
int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
|
||||
__u32 minor_hash,
|
||||
struct ext4_dir_entry_2 *dirent)
|
||||
struct ext4_dir_entry_2 *dirent,
|
||||
struct ext4_str *ent_name)
|
||||
{
|
||||
struct rb_node **p, *parent = NULL;
|
||||
struct fname *fname, *new_fn;
|
||||
@ -396,17 +401,17 @@ int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
|
||||
p = &info->root.rb_node;
|
||||
|
||||
/* Create and allocate the fname structure */
|
||||
len = sizeof(struct fname) + dirent->name_len + 1;
|
||||
len = sizeof(struct fname) + ent_name->len + 1;
|
||||
new_fn = kzalloc(len, GFP_KERNEL);
|
||||
if (!new_fn)
|
||||
return -ENOMEM;
|
||||
new_fn->hash = hash;
|
||||
new_fn->minor_hash = minor_hash;
|
||||
new_fn->inode = le32_to_cpu(dirent->inode);
|
||||
new_fn->name_len = dirent->name_len;
|
||||
new_fn->name_len = ent_name->len;
|
||||
new_fn->file_type = dirent->file_type;
|
||||
memcpy(new_fn->name, dirent->name, dirent->name_len);
|
||||
new_fn->name[dirent->name_len] = 0;
|
||||
memcpy(new_fn->name, ent_name->name, ent_name->len);
|
||||
new_fn->name[ent_name->len] = 0;
|
||||
|
||||
while (*p) {
|
||||
parent = *p;
|
||||
|
@ -2142,8 +2142,9 @@ extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *,
|
||||
unlikely(__ext4_check_dir_entry(__func__, __LINE__, (dir), (filp), \
|
||||
(de), (bh), (buf), (size), (offset)))
|
||||
extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
|
||||
__u32 minor_hash,
|
||||
struct ext4_dir_entry_2 *dirent);
|
||||
__u32 minor_hash,
|
||||
struct ext4_dir_entry_2 *dirent,
|
||||
struct ext4_str *ent_name);
|
||||
extern void ext4_htree_free_dir_info(struct dir_private_info *p);
|
||||
extern int ext4_find_dest_de(struct inode *dir, struct inode *inode,
|
||||
struct buffer_head *bh,
|
||||
|
@ -1327,6 +1327,7 @@ int htree_inlinedir_to_tree(struct file *dir_file,
|
||||
struct ext4_iloc iloc;
|
||||
void *dir_buf = NULL;
|
||||
struct ext4_dir_entry_2 fake;
|
||||
struct ext4_str tmp_str;
|
||||
|
||||
ret = ext4_get_inode_loc(inode, &iloc);
|
||||
if (ret)
|
||||
@ -1398,8 +1399,10 @@ int htree_inlinedir_to_tree(struct file *dir_file,
|
||||
continue;
|
||||
if (de->inode == 0)
|
||||
continue;
|
||||
err = ext4_htree_store_dirent(dir_file,
|
||||
hinfo->hash, hinfo->minor_hash, de);
|
||||
tmp_str.name = de->name;
|
||||
tmp_str.len = de->name_len;
|
||||
err = ext4_htree_store_dirent(dir_file, hinfo->hash,
|
||||
hinfo->minor_hash, de, &tmp_str);
|
||||
if (err) {
|
||||
count = err;
|
||||
goto out;
|
||||
|
@ -877,6 +877,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
|
||||
struct buffer_head *bh;
|
||||
struct ext4_dir_entry_2 *de, *top;
|
||||
int err = 0, count = 0;
|
||||
struct ext4_str tmp_str;
|
||||
|
||||
dxtrace(printk(KERN_INFO "In htree dirblock_to_tree: block %lu\n",
|
||||
(unsigned long)block));
|
||||
@ -903,8 +904,11 @@ static int htree_dirblock_to_tree(struct file *dir_file,
|
||||
continue;
|
||||
if (de->inode == 0)
|
||||
continue;
|
||||
if ((err = ext4_htree_store_dirent(dir_file,
|
||||
hinfo->hash, hinfo->minor_hash, de)) != 0) {
|
||||
tmp_str.name = de->name;
|
||||
tmp_str.len = de->name_len;
|
||||
err = ext4_htree_store_dirent(dir_file,
|
||||
hinfo->hash, hinfo->minor_hash, de, &tmp_str);
|
||||
if (err != 0) {
|
||||
brelse(bh);
|
||||
return err;
|
||||
}
|
||||
@ -934,6 +938,7 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
|
||||
int count = 0;
|
||||
int ret, err;
|
||||
__u32 hashval;
|
||||
struct ext4_str tmp_str;
|
||||
|
||||
dxtrace(printk(KERN_DEBUG "In htree_fill_tree, start hash: %x:%x\n",
|
||||
start_hash, start_minor_hash));
|
||||
@ -969,14 +974,22 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
|
||||
/* Add '.' and '..' from the htree header */
|
||||
if (!start_hash && !start_minor_hash) {
|
||||
de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data;
|
||||
if ((err = ext4_htree_store_dirent(dir_file, 0, 0, de)) != 0)
|
||||
tmp_str.name = de->name;
|
||||
tmp_str.len = de->name_len;
|
||||
err = ext4_htree_store_dirent(dir_file, 0, 0,
|
||||
de, &tmp_str);
|
||||
if (err != 0)
|
||||
goto errout;
|
||||
count++;
|
||||
}
|
||||
if (start_hash < 2 || (start_hash ==2 && start_minor_hash==0)) {
|
||||
de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data;
|
||||
de = ext4_next_entry(de, dir->i_sb->s_blocksize);
|
||||
if ((err = ext4_htree_store_dirent(dir_file, 2, 0, de)) != 0)
|
||||
tmp_str.name = de->name;
|
||||
tmp_str.len = de->name_len;
|
||||
err = ext4_htree_store_dirent(dir_file, 2, 0,
|
||||
de, &tmp_str);
|
||||
if (err != 0)
|
||||
goto errout;
|
||||
count++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user