Skip to contentSkip to conversation

btrfs-progs: Exit gracefully when overlap chunks are detected

PATCH In review Qu Wenruo 3 participants 4 messages Jul 9, 2018 – Jul 16, 2018 Btrfs file system

lore
Share & tools
lore

Qu Wenruo

author
#0 lore raw

PATCH 1/2 btrfs-progs: Exit gracefully when overlap chunks are detected

BUG_ON() can be triggered if some image contains overlap chunks. volumes.c:1930: read_one_chunk: BUG_ON ret triggered, value -17 btrfs(+0x2cf12)[0x5601efa17f12] btrfs(+0x2fd8b)[0x5601efa1ad8b] btrfs(btrfs_read_chunk_tree+0x2bf)[0x5601efa1b30f] btrfs(btrfs_setup_chunk_tree_and_device_map+0xe8)[0x5601efa07718] btrfs(+0x1c944)[0x5601efa07944] btrfs(open_ctree_fs_info+0x90)[0x5601efa07b90] btrfs(cmd_check+0x4d7)[0x5601efa4f8c7] btrfs(main+0x88)[0x5601ef9fd768] /usr/lib/libc.so.6(__libc_start_main+0xeb)[0x7f3c7787306b] btrfs(_start+0x2a)[0x5601ef9fd88a]

Extent cache code can already detect it without problem, we only need to remove the BUG_ON() and exit gracefully.

---
 volumes.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
volumes.c +5 -2
index 24eb3e8b2578..21a1fc31fcba 100644
@@ -1924,9 +1924,12 @@ static int read_one_chunk(struct btrfs_fs_info *fs_info, struct btrfs_key *key,
 
 	}
 	ret = insert_cache_extent(&map_tree->cache_tree, &map->ce);
-	BUG_ON(ret);
+	if (ret < 0) {
+		error("failed to add chunk map start=%llu len=%llu: %d (%s)",
+		      map->ce.start, map->ce.size, ret, strerror(-ret));
+	}
 
-	return 0;
+	return ret;
 }
 
 static int fill_device_from_item(struct extent_buffer *leaf,
Signature · 1 line
2.18.0
author
#1 lore raw

PATCH 2/2 btrfs-progs: tests/fuzz: Add image for bko-200409

---
 tests/fuzz-tests/images/bko-200409.raw.txt | 125 +++++++++++++++++++++
 tests/fuzz-tests/images/bko-200409.raw.xz  | Bin 0 -> 24480 bytes
 2 files changed, 125 insertions(+)
 create mode 100644 tests/fuzz-tests/images/bko-200409.raw.txt
 create mode 100644 tests/fuzz-tests/images/bko-200409.raw.xz
tests/fuzz-tests/images/bko-200409.raw.txt new file +125 -0
new file mode 100644
index 000000000000..7df7924370eb
@@ -0,0 +1,125 @@
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=200409
+Wen Xu 2018-07-04 17:47:09 UTC
+
+Created attachment 277173 [details]
+The (compressed) crafted image which causes crash
+
+- Reproduce
+# mkdir mnt
+# mount -t btrfs 5.img mnt
+
+- Kernel message
+[  333.770743] BTRFS: device fsid 3381d111-94a3-4ac7-8f39-611bbbdab7e6 devid 1 transid 8 /dev/loop0
+[  333.779221] BTRFS info (device loop0): disk space caching is enabled
+[  333.779234] BTRFS info (device loop0): has skinny extents
+[  333.798081] ------------[ cut here ]------------
+[  333.798090] kernel BUG at fs/btrfs/volumes.c:6564!
+[  333.799293] invalid opcode: 0000 [#1] SMP KASAN PTI
+[  333.800355] CPU: 0 PID: 1353 Comm: mount Not tainted 4.18.0-rc1+ #8
+[  333.801652] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
+[  333.803658] RIP: 0010:read_one_chunk+0x77c/0x880
+[  333.804630] Code: e8 a9 82 fd ff 48 8b 95 70 ff ff ff 48 8b bd 60 ff ff ff b9 01 00 00 00 4c 89 f6 e8 2e 14 ff ff b8 fe ff ff ff e9 cb fe ff ff <0f> 0b 48 8b bd 38 ff ff ff e8 76 82 fd ff e9 35 ff ff ff 48 8b 95
+[  333.808462] RSP: 0018:ffff8801eedf7230 EFLAGS: 00010282
+[  333.809542] RAX: ffff8801f2df2100 RBX: 00000000ffffffef RCX: ffffffffa5839143
+[  333.810991] RDX: 1ffff1003e5be444 RSI: e300000001c00000 RDI: ffff8801f2df2220
+[  333.812451] RBP: ffff8801eedf7310 R08: ffffed003e5be445 R09: ffffed003e5be445
+[  333.813905] R10: 0000000000000001 R11: ffffed003e5be444 R12: ffff8801e6788158
+[  333.815357] R13: 0000000000000001 R14: 0000000000000001 R15: ffff8801f2df2220
+[  333.846990] FS:  00007f2013519840(0000) GS:ffff8801f6e00000(0000) knlGS:0000000000000000
+[  333.848645] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  333.849816] CR2: 00007f88a3c6b760 CR3: 00000001e655e000 CR4: 00000000000006f0
+[  333.851304] Call Trace:
+[  333.851864]  ? add_missing_dev+0xc0/0xc0
+[  333.852715]  ? read_extent_buffer+0xe9/0x130
+[  333.853604]  btrfs_read_chunk_tree+0x957/0xd20
+[  333.854551]  ? free_root_pointers+0xb0/0xb0
+[  333.855435]  ? btrfs_check_rw_degradable+0x240/0x240
+[  333.856491]  ? btree_read_extent_buffer_pages+0x1e0/0x3b0
+[  333.857617]  ? run_one_async_done+0xb0/0xb0
+[  333.858498]  ? cache_state.part.32+0x10/0x40
+[  333.859430]  ? unlock_page+0x16/0x40
+[  333.860202]  ? alloc_extent_buffer+0x4a1/0x4e0
+[  333.861149]  ? memcpy+0x45/0x50
+[  333.861818]  ? read_extent_buffer+0xe9/0x130
+[  333.862711]  open_ctree+0x246c/0x35c6
+[  333.863488]  ? close_ctree+0x460/0x460
+[  333.864302]  ? bdi_register_va+0x44/0x50
+[  333.865142]  ? super_setup_bdi_name+0x11b/0x1a0
+[  333.866089]  ? kill_block_super+0x80/0x80
+[  333.866970]  ? snprintf+0x96/0xd0
+[  333.867704]  btrfs_mount_root+0xae6/0xc60
+[  333.868550]  ? btrfs_mount_root+0xae6/0xc60
+[  333.869419]  ? pcpu_block_update_hint_alloc+0x1d2/0x2a0
+[  333.870492]  ? btrfs_decode_error+0x40/0x40
+[  333.871389]  ? find_next_bit+0x57/0x90
+[  333.872206]  ? cpumask_next+0x1a/0x20
+[  333.872986]  ? pcpu_alloc+0x449/0x8c0
+[  333.873761]  ? pcpu_free_area+0x410/0x410
+[  333.874614]  ? memcg_kmem_put_cache+0x1b/0xa0
+[  333.875531]  ? memcpy+0x45/0x50
+[  333.876209]  mount_fs+0x60/0x1a0
+[  333.876892]  ? btrfs_decode_error+0x40/0x40
+[  333.877763]  ? mount_fs+0x60/0x1a0
+[  333.878492]  ? alloc_vfsmnt+0x309/0x360
+[  333.879303]  vfs_kern_mount+0x6b/0x1a0
+[  333.880121]  ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
+[  333.881209]  btrfs_mount+0x209/0xb71
+[  333.881962]  ? pcpu_block_update_hint_alloc+0x1d2/0x2a0
+[  333.883044]  ? btrfs_remount+0x8e0/0x8e0
+[  333.883878]  ? find_next_zero_bit+0x2c/0xa0
+[  333.884753]  ? find_next_bit+0x57/0x90
+[  333.885538]  ? cpumask_next+0x1a/0x20
+[  333.886307]  ? pcpu_alloc+0x449/0x8c0
+[  333.887078]  ? pcpu_free_area+0x410/0x410
+[  333.887930]  ? memcg_kmem_put_cache+0x1b/0xa0
+[  333.888836]  ? memcpy+0x45/0x50
+[  333.889500]  mount_fs+0x60/0x1a0
+[  333.890182]  ? btrfs_remount+0x8e0/0x8e0
+[  333.891001]  ? mount_fs+0x60/0x1a0
+[  333.891728]  ? alloc_vfsmnt+0x309/0x360
+[  333.892533]  vfs_kern_mount+0x6b/0x1a0
+[  333.893323]  do_mount+0x34a/0x18c0
+[  333.894042]  ? copy_mount_string+0x20/0x20
+[  333.894898]  ? memcg_kmem_put_cache+0x1b/0xa0
+[  333.895832]  ? kasan_check_write+0x14/0x20
+[  333.896704]  ? _copy_from_user+0x6a/0x90
+[  333.897542]  ? memdup_user+0x42/0x60
+[  333.898300]  ksys_mount+0x83/0xd0
+[  333.899003]  __x64_sys_mount+0x67/0x80
+[  333.899831]  do_syscall_64+0x78/0x170
+[  333.900610]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
+[  333.901682] RIP: 0033:0x7f2012df9b9a
+[  333.902430] Code: 48 8b 0d 01 c3 2b 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d ce c2 2b 00 f7 d8 64 89 01 48
+[  333.906311] RSP: 002b:00007ffd77e261b8 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
+[  333.907874] RAX: ffffffffffffffda RBX: 00000000019e7030 RCX: 00007f2012df9b9a
+[  333.909341] RDX: 00000000019e7210 RSI: 00000000019e8f30 RDI: 00000000019efec0
+[  333.910804] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000014
+[  333.912281] R10: 00000000c0ed0000 R11: 0000000000000206 R12: 00000000019efec0
+[  333.913747] R13: 00000000019e7210 R14: 0000000000000000 R15: 0000000000000003
+[  333.915224] Modules linked in: snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd mac_hid i2c_piix4 soundcore ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx raid1 raid0 multipath linear 8139too qxl drm_kms_helper crct10dif_pclmul syscopyarea sysfillrect sysimgblt fb_sys_fops ttm crc32_pclmul aesni_intel drm aes_x86_64 crypto_simd cryptd glue_helper 8139cp mii pata_acpi floppy
+[  333.932460] ---[ end trace 2e85051acb5f6dc1 ]---
+[  333.933448] RIP: 0010:read_one_chunk+0x77c/0x880
+[  333.934397] Code: e8 a9 82 fd ff 48 8b 95 70 ff ff ff 48 8b bd 60 ff ff ff b9 01 00 00 00 4c 89 f6 e8 2e 14 ff ff b8 fe ff ff ff e9 cb fe ff ff <0f> 0b 48 8b bd 38 ff ff ff e8 76 82 fd ff e9 35 ff ff ff 48 8b 95
+[  333.938283] RSP: 0018:ffff8801eedf7230 EFLAGS: 00010282
+[  333.939361] RAX: ffff8801f2df2100 RBX: 00000000ffffffef RCX: ffffffffa5839143
+[  333.940846] RDX: 1ffff1003e5be444 RSI: e300000001c00000 RDI: ffff8801f2df2220
+[  333.942318] RBP: ffff8801eedf7310 R08: ffffed003e5be445 R09: ffffed003e5be445
+[  333.943878] R10: 0000000000000001 R11: ffffed003e5be444 R12: ffff8801e6788158
+[  333.945371] R13: 0000000000000001 R14: 0000000000000001 R15: ffff8801f2df2220
+[  333.946839] FS:  00007f2013519840(0000) GS:ffff8801f6e00000(0000) knlGS:0000000000000000
+[  333.948526] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  333.949711] CR2: 00007f88a3c6b760 CR3: 00000001e655e000 CR4: 00000000000006f0
+
+- Location
+https://elixir.bootlin.com/linux/v4.18-rc3/source/fs/btrfs/volumes.c#L6564
+	write_lock(&map_tree->map_tree.lock);
+	ret = add_extent_mapping(&map_tree->map_tree, em, 0);
+	write_unlock(&map_tree->map_tree.lock);
+	BUG_ON(ret); /* Tree corruption */ <---
+	free_extent_map(em);
+
+Found by Wen Xu and Po-Ning Tseng from SSLab at Gatech.
+
+====== Extra info for btrfs-progs ======
+Btrfs-progs has the exact BUG_ON() in read_one_chunk().
+Fixed by "btrfs-progs: Exit gracefully when overlap chunks are detected".
tests/fuzz-tests/images/bko-200409.raw.xz new file binary +0 -0
new file mode 100644
index 0000000000000000000000000000000000000000..8ec29cfd61420fd20924d7208a74205f08a3d7e3
GIT binary patch
Signature · 1 line
2.18.0
Reviewed-by on v1 1/2
#2 lore raw
In reply to Qu Wenruo
Quoted 13 lines · Qu Wenruo

BUG_ON() can be triggered if some image contains overlap chunks. volumes.c:1930: read_one_chunk: BUG_ON ret triggered, value -17 btrfs(+0x2cf12)[0x5601efa17f12] btrfs(+0x2fd8b)[0x5601efa1ad8b] btrfs(btrfs_read_chunk_tree+0x2bf)[0x5601efa1b30f] btrfs(btrfs_setup_chunk_tree_and_device_map+0xe8)[0x5601efa07718] btrfs(+0x1c944)[0x5601efa07944] btrfs(open_ctree_fs_info+0x90)[0x5601efa07b90] btrfs(cmd_check+0x4d7)[0x5601efa4f8c7] btrfs(main+0x88)[0x5601ef9fd768] /usr/lib/libc.so.6(__libc_start_main+0xeb)[0x7f3c7787306b] btrfs(_start+0x2a)[0x5601ef9fd88a]

Quoted 6 lines

Extent cache code can already detect it without problem, we only need to remove the BUG_ON() and exit gracefully.

Quoted 24 lines
---
 volumes.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
volumes.c +5 -2
index 24eb3e8b2578..21a1fc31fcba 100644
@@ -1924,9 +1924,12 @@ static int read_one_chunk(struct btrfs_fs_info *fs_info, struct btrfs_key *key,
 
 	}
 	ret = insert_cache_extent(&map_tree->cache_tree, &map->ce);
-	BUG_ON(ret);
+	if (ret < 0) {
+		error("failed to add chunk map start=%llu len=%llu: %d (%s)",
+		      map->ce.start, map->ce.size, ret, strerror(-ret));
+	}
 
-	return 0;
+	return ret;
 }
 
 static int fill_device_from_item(struct extent_buffer *leaf,
#3 lore raw
In reply to Qu Wenruo
Quoted 13 lines · Qu Wenruo

BUG_ON() can be triggered if some image contains overlap chunks. volumes.c:1930: read_one_chunk: BUG_ON ret triggered, value -17 btrfs(+0x2cf12)[0x5601efa17f12] btrfs(+0x2fd8b)[0x5601efa1ad8b] btrfs(btrfs_read_chunk_tree+0x2bf)[0x5601efa1b30f] btrfs(btrfs_setup_chunk_tree_and_device_map+0xe8)[0x5601efa07718] btrfs(+0x1c944)[0x5601efa07944] btrfs(open_ctree_fs_info+0x90)[0x5601efa07b90] btrfs(cmd_check+0x4d7)[0x5601efa4f8c7] btrfs(main+0x88)[0x5601ef9fd768] /usr/lib/libc.so.6(__libc_start_main+0xeb)[0x7f3c7787306b] btrfs(_start+0x2a)[0x5601ef9fd88a]

Quoted 6 lines

Extent cache code can already detect it without problem, we only need to remove the BUG_ON() and exit gracefully.

1 and 2 applied, thanks.