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