summaryrefslogtreecommitdiff
path: root/cmds-restore.c
diff options
context:
space:
mode:
authorGui Hecheng <guihc.fnst@cn.fujitsu.com>2014-08-28 10:25:53 +0800
committerDavid Sterba <dsterba@suse.cz>2014-09-14 14:49:00 +0200
commitc7d16e08bdca950f615c4103dd1a4d8d7f810ab1 (patch)
treec6794a9bdf1bdc6a2c25ff91697cc14f24f329ff /cmds-restore.c
parent977f2baf363b59d4263d870b292975e2b791cd07 (diff)
downloadbtrfs-progs-c7d16e08bdca950f615c4103dd1a4d8d7f810ab1.tar.gz
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>
Diffstat (limited to 'cmds-restore.c')
-rw-r--r--cmds-restore.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/cmds-restore.c b/cmds-restore.c
index e2bcbf9..bc67708 100644
--- a/cmds-restore.c
+++ b/cmds-restore.c
@@ -231,13 +231,15 @@ static int copy_one_inline(int fd, struct btrfs_path *path, u64 pos)
unsigned long ptr;
int ret;
int len;
+ int inline_item_len;
int compress;
fi = btrfs_item_ptr(leaf, path->slots[0],
struct btrfs_file_extent_item);
ptr = btrfs_file_extent_inline_start(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);
if (compress == BTRFS_COMPRESS_NONE) {