btrfs-progs: fix len of read_extent_buffer for inline extent in restore

Steps to reproduce:
	# mkfs.btrfs -f <dev>
	# mount -o compress-force=lzo <dev> <mnt>
	# for ((i=0;i<4000;i++)); do
	  	echo -n 'A' >> <mnt>/inline_data
	  done
	# umount <mnt>
	# valgrind --tool=memcheck --leak-check=full	\
	  btrfs restore <dev> <dest_dir>
output:
	==32118== Invalid read of size 1
	==32118==    at 0x4A0A4E4: memcpy@@GLIBC_2.14
	==32118==    by 0x43DC91: read_extent_buffer
	==32118==    by 0x421401: search_dir (cmds-restore.c:240)
	==32118==    by 0x422CBB: cmd_restore (cmds-restore.c:1317)
	==32118==    by 0x404709: main (btrfs.c:248)
	==32118==  Address 0x4c4f4ac is not stack'd, malloc'd or...

It is because when deal with inline extent, the read_extent_buffer
is now reading a len of @ram_bytes which is the len of the uncompressed
data. But actually here we want the len of the inline item.
So in the compressed situation, use the len of the inline item.

Signed-off-by: Gui Hecheng <guihc.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
This commit is contained in:
Gui Hecheng 2014-08-28 10:25:53 +08:00 committed by David Sterba
parent 977f2baf36
commit c7d16e08bd
1 changed files with 3 additions and 1 deletions

View File

@ -231,13 +231,15 @@ static int copy_one_inline(int fd, struct btrfs_path *path, u64 pos)
unsigned long ptr; unsigned long ptr;
int ret; int ret;
int len; int len;
int inline_item_len;
int compress; int compress;
fi = btrfs_item_ptr(leaf, path->slots[0], fi = btrfs_item_ptr(leaf, path->slots[0],
struct btrfs_file_extent_item); struct btrfs_file_extent_item);
ptr = btrfs_file_extent_inline_start(fi); ptr = btrfs_file_extent_inline_start(fi);
len = btrfs_file_extent_inline_len(leaf, path->slots[0], fi); len = btrfs_file_extent_inline_len(leaf, path->slots[0], fi);
read_extent_buffer(leaf, buf, ptr, len); inline_item_len = btrfs_file_extent_inline_item_len(leaf, btrfs_item_nr(path->slots[0]));
read_extent_buffer(leaf, buf, ptr, inline_item_len);
compress = btrfs_file_extent_compression(leaf, fi); compress = btrfs_file_extent_compression(leaf, fi);
if (compress == BTRFS_COMPRESS_NONE) { if (compress == BTRFS_COMPRESS_NONE) {