diff options
author | Theodore Ts'o <tytso@mit.edu> | 2015-04-12 00:56:26 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2015-04-12 00:56:26 -0400 |
commit | 2f61830ae33e2944ad66bb8bb40916f534b2e494 (patch) | |
tree | 7bd66dc3c940e88bea7b01db6b15199e25e5716e | |
parent | d5d0e8c7203a41c01ba05f4e053e16a94ce3c2e1 (diff) |
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>
-rw-r--r-- | fs/ext4/dir.c | 15 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 5 | ||||
-rw-r--r-- | fs/ext4/inline.c | 7 | ||||
-rw-r--r-- | fs/ext4/namei.c | 21 |
4 files changed, 35 insertions, 13 deletions
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 9e1e9e7869cb..315f13ad382e 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c | |||
@@ -382,10 +382,15 @@ void ext4_htree_free_dir_info(struct dir_private_info *p) | |||
382 | 382 | ||
383 | /* | 383 | /* |
384 | * Given a directory entry, enter it into the fname rb tree. | 384 | * Given a directory entry, enter it into the fname rb tree. |
385 | * | ||
386 | * When filename encryption is enabled, the dirent will hold the | ||
387 | * encrypted filename, while the htree will hold decrypted filename. | ||
388 | * The decrypted filename is passed in via ent_name. parameter. | ||
385 | */ | 389 | */ |
386 | int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, | 390 | int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, |
387 | __u32 minor_hash, | 391 | __u32 minor_hash, |
388 | struct ext4_dir_entry_2 *dirent) | 392 | struct ext4_dir_entry_2 *dirent, |
393 | struct ext4_str *ent_name) | ||
389 | { | 394 | { |
390 | struct rb_node **p, *parent = NULL; | 395 | struct rb_node **p, *parent = NULL; |
391 | struct fname *fname, *new_fn; | 396 | struct fname *fname, *new_fn; |
@@ -396,17 +401,17 @@ int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, | |||
396 | p = &info->root.rb_node; | 401 | p = &info->root.rb_node; |
397 | 402 | ||
398 | /* Create and allocate the fname structure */ | 403 | /* Create and allocate the fname structure */ |
399 | len = sizeof(struct fname) + dirent->name_len + 1; | 404 | len = sizeof(struct fname) + ent_name->len + 1; |
400 | new_fn = kzalloc(len, GFP_KERNEL); | 405 | new_fn = kzalloc(len, GFP_KERNEL); |
401 | if (!new_fn) | 406 | if (!new_fn) |
402 | return -ENOMEM; | 407 | return -ENOMEM; |
403 | new_fn->hash = hash; | 408 | new_fn->hash = hash; |
404 | new_fn->minor_hash = minor_hash; | 409 | new_fn->minor_hash = minor_hash; |
405 | new_fn->inode = le32_to_cpu(dirent->inode); | 410 | new_fn->inode = le32_to_cpu(dirent->inode); |
406 | new_fn->name_len = dirent->name_len; | 411 | new_fn->name_len = ent_name->len; |
407 | new_fn->file_type = dirent->file_type; | 412 | new_fn->file_type = dirent->file_type; |
408 | memcpy(new_fn->name, dirent->name, dirent->name_len); | 413 | memcpy(new_fn->name, ent_name->name, ent_name->len); |
409 | new_fn->name[dirent->name_len] = 0; | 414 | new_fn->name[ent_name->len] = 0; |
410 | 415 | ||
411 | while (*p) { | 416 | while (*p) { |
412 | parent = *p; | 417 | parent = *p; |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 3462532b227f..ba75838f3588 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -2142,8 +2142,9 @@ extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *, | |||
2142 | unlikely(__ext4_check_dir_entry(__func__, __LINE__, (dir), (filp), \ | 2142 | unlikely(__ext4_check_dir_entry(__func__, __LINE__, (dir), (filp), \ |
2143 | (de), (bh), (buf), (size), (offset))) | 2143 | (de), (bh), (buf), (size), (offset))) |
2144 | extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, | 2144 | extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, |
2145 | __u32 minor_hash, | 2145 | __u32 minor_hash, |
2146 | struct ext4_dir_entry_2 *dirent); | 2146 | struct ext4_dir_entry_2 *dirent, |
2147 | struct ext4_str *ent_name); | ||
2147 | extern void ext4_htree_free_dir_info(struct dir_private_info *p); | 2148 | extern void ext4_htree_free_dir_info(struct dir_private_info *p); |
2148 | extern int ext4_find_dest_de(struct inode *dir, struct inode *inode, | 2149 | extern int ext4_find_dest_de(struct inode *dir, struct inode *inode, |
2149 | struct buffer_head *bh, | 2150 | struct buffer_head *bh, |
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 8b64d715e476..661f0b8dcfe0 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c | |||
@@ -1327,6 +1327,7 @@ int htree_inlinedir_to_tree(struct file *dir_file, | |||
1327 | struct ext4_iloc iloc; | 1327 | struct ext4_iloc iloc; |
1328 | void *dir_buf = NULL; | 1328 | void *dir_buf = NULL; |
1329 | struct ext4_dir_entry_2 fake; | 1329 | struct ext4_dir_entry_2 fake; |
1330 | struct ext4_str tmp_str; | ||
1330 | 1331 | ||
1331 | ret = ext4_get_inode_loc(inode, &iloc); | 1332 | ret = ext4_get_inode_loc(inode, &iloc); |
1332 | if (ret) | 1333 | if (ret) |
@@ -1398,8 +1399,10 @@ int htree_inlinedir_to_tree(struct file *dir_file, | |||
1398 | continue; | 1399 | continue; |
1399 | if (de->inode == 0) | 1400 | if (de->inode == 0) |
1400 | continue; | 1401 | continue; |
1401 | err = ext4_htree_store_dirent(dir_file, | 1402 | tmp_str.name = de->name; |
1402 | hinfo->hash, hinfo->minor_hash, de); | 1403 | tmp_str.len = de->name_len; |
1404 | err = ext4_htree_store_dirent(dir_file, hinfo->hash, | ||
1405 | hinfo->minor_hash, de, &tmp_str); | ||
1403 | if (err) { | 1406 | if (err) { |
1404 | count = err; | 1407 | count = err; |
1405 | goto out; | 1408 | goto out; |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 77a63ff4aeb9..8cef115ee64a 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -877,6 +877,7 @@ static int htree_dirblock_to_tree(struct file *dir_file, | |||
877 | struct buffer_head *bh; | 877 | struct buffer_head *bh; |
878 | struct ext4_dir_entry_2 *de, *top; | 878 | struct ext4_dir_entry_2 *de, *top; |
879 | int err = 0, count = 0; | 879 | int err = 0, count = 0; |
880 | struct ext4_str tmp_str; | ||
880 | 881 | ||
881 | dxtrace(printk(KERN_INFO "In htree dirblock_to_tree: block %lu\n", | 882 | dxtrace(printk(KERN_INFO "In htree dirblock_to_tree: block %lu\n", |
882 | (unsigned long)block)); | 883 | (unsigned long)block)); |
@@ -903,8 +904,11 @@ static int htree_dirblock_to_tree(struct file *dir_file, | |||
903 | continue; | 904 | continue; |
904 | if (de->inode == 0) | 905 | if (de->inode == 0) |
905 | continue; | 906 | continue; |
906 | if ((err = ext4_htree_store_dirent(dir_file, | 907 | tmp_str.name = de->name; |
907 | hinfo->hash, hinfo->minor_hash, de)) != 0) { | 908 | tmp_str.len = de->name_len; |
909 | err = ext4_htree_store_dirent(dir_file, | ||
910 | hinfo->hash, hinfo->minor_hash, de, &tmp_str); | ||
911 | if (err != 0) { | ||
908 | brelse(bh); | 912 | brelse(bh); |
909 | return err; | 913 | return err; |
910 | } | 914 | } |
@@ -934,6 +938,7 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash, | |||
934 | int count = 0; | 938 | int count = 0; |
935 | int ret, err; | 939 | int ret, err; |
936 | __u32 hashval; | 940 | __u32 hashval; |
941 | struct ext4_str tmp_str; | ||
937 | 942 | ||
938 | dxtrace(printk(KERN_DEBUG "In htree_fill_tree, start hash: %x:%x\n", | 943 | dxtrace(printk(KERN_DEBUG "In htree_fill_tree, start hash: %x:%x\n", |
939 | start_hash, start_minor_hash)); | 944 | start_hash, start_minor_hash)); |
@@ -969,14 +974,22 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash, | |||
969 | /* Add '.' and '..' from the htree header */ | 974 | /* Add '.' and '..' from the htree header */ |
970 | if (!start_hash && !start_minor_hash) { | 975 | if (!start_hash && !start_minor_hash) { |
971 | de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data; | 976 | de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data; |
972 | if ((err = ext4_htree_store_dirent(dir_file, 0, 0, de)) != 0) | 977 | tmp_str.name = de->name; |
978 | tmp_str.len = de->name_len; | ||
979 | err = ext4_htree_store_dirent(dir_file, 0, 0, | ||
980 | de, &tmp_str); | ||
981 | if (err != 0) | ||
973 | goto errout; | 982 | goto errout; |
974 | count++; | 983 | count++; |
975 | } | 984 | } |
976 | if (start_hash < 2 || (start_hash ==2 && start_minor_hash==0)) { | 985 | if (start_hash < 2 || (start_hash ==2 && start_minor_hash==0)) { |
977 | de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data; | 986 | de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data; |
978 | de = ext4_next_entry(de, dir->i_sb->s_blocksize); | 987 | de = ext4_next_entry(de, dir->i_sb->s_blocksize); |
979 | if ((err = ext4_htree_store_dirent(dir_file, 2, 0, de)) != 0) | 988 | tmp_str.name = de->name; |
989 | tmp_str.len = de->name_len; | ||
990 | err = ext4_htree_store_dirent(dir_file, 2, 0, | ||
991 | de, &tmp_str); | ||
992 | if (err != 0) | ||
980 | goto errout; | 993 | goto errout; |
981 | count++; | 994 | count++; |
982 | } | 995 | } |