diff --git a/tests/fuzz-tests/images/bad-superblock-1.raw.xz b/tests/fuzz-tests/images/bad-superblock-1.raw.xz new file mode 100644 index 00000000..3d6358f0 Binary files /dev/null and b/tests/fuzz-tests/images/bad-superblock-1.raw.xz differ diff --git a/tests/fuzz-tests/images/bad-superblock-2.raw.xz b/tests/fuzz-tests/images/bad-superblock-2.raw.xz new file mode 100644 index 00000000..7db7610b Binary files /dev/null and b/tests/fuzz-tests/images/bad-superblock-2.raw.xz differ diff --git a/tests/fuzz-tests/images/bad-superblock-3.raw.xz b/tests/fuzz-tests/images/bad-superblock-3.raw.xz new file mode 100644 index 00000000..4aa31483 Binary files /dev/null and b/tests/fuzz-tests/images/bad-superblock-3.raw.xz differ diff --git a/tests/fuzz-tests/images/bad-superblock.txt b/tests/fuzz-tests/images/bad-superblock.txt new file mode 100644 index 00000000..f7dd9aa0 --- /dev/null +++ b/tests/fuzz-tests/images/bad-superblock.txt @@ -0,0 +1,17 @@ +bad-superblock-*.txt + +Crafted images from Jiri Slaby, produced by some symbolic execution framework +that finds unhandled cases at mount time. + +Relevant kernel patches to backport: + +e3540eab29e1b2260bc4b9b3979a49a00e3e3af8 +btrfs: add more checks to btrfs_read_sys_array + +ce7fca5f57ed0fcd7e7b3d7b1a3e1791f8e56fa3 +btrfs: add checks for sys_chunk_array sizes + +75d6ad382bb91f363452119d34238e156589ca2d +btrfs: more superblock checks, lower bounds on devices and sectorsize/nodesize + +(and more from fs/btrfs/super.c) diff --git a/tests/fuzz-tests/images/bko-104131-fsck-oob-read.raw.xz b/tests/fuzz-tests/images/bko-104131-fsck-oob-read.raw.xz new file mode 100644 index 00000000..7848f8b1 Binary files /dev/null and b/tests/fuzz-tests/images/bko-104131-fsck-oob-read.raw.xz differ diff --git a/tests/fuzz-tests/images/bko-104131-fsck-oob-read.txt b/tests/fuzz-tests/images/bko-104131-fsck-oob-read.txt new file mode 100644 index 00000000..0e829c2e --- /dev/null +++ b/tests/fuzz-tests/images/bko-104131-fsck-oob-read.txt @@ -0,0 +1,31 @@ +URL: https://bugzilla.kernel.org/show_bug.cgi?id=104131 +Hanno Boeck 2015-09-07 07:24:32 UTC + +Created attachment 186941 [details] +malformed btrfs filesystem causing oob read + +The attached malformed filesystem image will cause an invalid heap out of bounds memory read in btrfsck. + +This was found while fuzzing btrfs-progs with american fuzzy lop. + +Stack trace from Address Sanitizer: +==31289==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60f00000f003 at pc 0x0000005d0dbb bp 0x7ffdf444c180 sp 0x7ffdf444c178 +READ of size 8 at 0x60f00000f003 thread T0 + #0 0x5d0dba in btrfs_header_bytenr /mnt/ram/btrfs-progs-v4.1.2/./ctree.h:1797:1 + #1 0x5d0dba in check_tree_block /mnt/ram/btrfs-progs-v4.1.2/disk-io.c:60 + #2 0x5d0dba in read_tree_block /mnt/ram/btrfs-progs-v4.1.2/disk-io.c:337 + #3 0x5dc00e in btrfs_setup_chunk_tree_and_device_map /mnt/ram/btrfs-progs-v4.1.2/disk-io.c:1169:30 + #4 0x5dcf89 in __open_ctree_fd /mnt/ram/btrfs-progs-v4.1.2/disk-io.c:1261:8 + #5 0x5dc50a in open_ctree_fs_info /mnt/ram/btrfs-progs-v4.1.2/disk-io.c:1302:9 + #6 0x52f22f in cmd_check /mnt/ram/btrfs-progs-v4.1.2/cmds-check.c:9333:9 + #7 0x4e7bcc in main /mnt/ram/btrfs-progs-v4.1.2/btrfs.c:245:7 + #8 0x7f98bb101f9f in __libc_start_main /var/tmp/portage/sys-libs/glibc-2.20-r2/work/glibc-2.20/csu/libc-start.c:289 + #9 0x41f748 in _start (/mnt/ram/btrfs/btrfs+0x41f748) + +0x60f00000f003 is located 3 bytes to the right of 176-byte region [0x60f00000ef50,0x60f00000f000) +allocated by thread T0 here: + #0 0x4bade8 in malloc (/mnt/ram/btrfs/btrfs+0x4bade8) + #1 0x622c24 in __alloc_extent_buffer /mnt/ram/btrfs-progs-v4.1.2/extent_io.c:541:7 + #2 0x622c24 in alloc_extent_buffer /mnt/ram/btrfs-progs-v4.1.2/extent_io.c:648 + #3 0x5cf436 in btrfs_find_create_tree_block /mnt/ram/btrfs-progs-v4.1.2/disk-io.c:186:9 + #4 0x5cf436 in read_tree_block /mnt/ram/btrfs-progs-v4.1.2/disk-io.c:314 diff --git a/tests/fuzz-tests/images/bko-104141-fsck-exception.raw.xz b/tests/fuzz-tests/images/bko-104141-fsck-exception.raw.xz new file mode 100644 index 00000000..d24a32f8 Binary files /dev/null and b/tests/fuzz-tests/images/bko-104141-fsck-exception.raw.xz differ diff --git a/tests/fuzz-tests/images/bko-104141-fsck-exception.txt b/tests/fuzz-tests/images/bko-104141-fsck-exception.txt new file mode 100644 index 00000000..aed91909 --- /dev/null +++ b/tests/fuzz-tests/images/bko-104141-fsck-exception.txt @@ -0,0 +1,9 @@ +URL: https://bugzilla.kernel.org/show_bug.cgi?id=104141 +Hanno Boeck 2015-09-07 07:27:58 UTC + +Created attachment 186951 [details] +malformed filesystem causing floating point exception + +The attacked file will cause a floating point exception in btrfsck. + +This was found while fuzzing btrfs-progs with american fuzzy lop. diff --git a/tests/fuzz-tests/images/bko-97191-btrfs-image.raw.txt b/tests/fuzz-tests/images/bko-97191-btrfs-image.raw.txt new file mode 100644 index 00000000..f0d81894 --- /dev/null +++ b/tests/fuzz-tests/images/bko-97191-btrfs-image.raw.txt @@ -0,0 +1,137 @@ +URL: https://bugzilla.kernel.org/show_bug.cgi?id=97191 +Lukas Lueg 2015-04-23 22:20:35 UTC + +Running btrfs-progs v3.19.1 + +The btrfs-image attached to this bug causes the btrfs-userland tool to +overflow some data structures, leading to unallocated memory being written to +and read from. A segfault results shortly after. Reproduced on x86-64 and +i686. + +The kernel seems to be less affected and fails to mount the image. I didn't +investigate whether the reads/writes could be used to gain control over $EIP. +Since the first invalid write of 8 bytes seems to run into adjacent heap +blocks (crash in unlink()), it may be possible though. + +gdb output: + +Program received signal SIGSEGV, Segmentation fault. +malloc_consolidate (av=av@entry=0x32629b7cc0 ) at malloc.c:4151 +4151 unlink(av, p, bck, fwd); +(gdb) bt +#0 malloc_consolidate (av=av@entry=0x32629b7cc0 ) at malloc.c:4151 +#1 0x0000003262680628 in _int_malloc (av=av@entry=0x32629b7cc0 , bytes=bytes@entry=4224) at malloc.c:3420 +#2 0x000000326268315e in __GI___libc_malloc (bytes=4224) at malloc.c:2896 +#3 0x0000000000449d15 in __alloc_extent_buffer (tree=0x88c078, bytenr=4288512, blocksize=4096) at extent_io.c:541 +#4 0x000000000044a8b4 in alloc_extent_buffer (tree=0x88c078, bytenr=4288512, blocksize=4096) at extent_io.c:648 +#5 0x000000000043b1a0 in btrfs_find_create_tree_block (root=root@entry=0x895840, bytenr=, + blocksize=) at disk-io.c:159 +#6 0x000000000043ca4e in read_tree_block (root=root@entry=0x895840, bytenr=, blocksize=, + parent_transid=13) at disk-io.c:287 +#7 0x000000000043ccb7 in find_and_setup_root (tree_root=0x88c250, fs_info=, objectid=5, root=0x895840) + at disk-io.c:557 +#8 0x000000000043ce92 in btrfs_read_fs_root_no_cache (fs_info=fs_info@entry=0x88c010, location=location@entry=0x7fffffffd960) + at disk-io.c:640 +#9 0x000000000043d060 in btrfs_read_fs_root (fs_info=fs_info@entry=0x88c010, location=location@entry=0x7fffffffd960) + at disk-io.c:739 +#10 0x000000000043d48c in btrfs_setup_all_roots (fs_info=fs_info@entry=0x88c010, root_tree_bytenr=, + root_tree_bytenr@entry=0, flags=flags@entry=OPEN_CTREE_EXCLUSIVE) at disk-io.c:988 +#11 0x000000000043d802 in __open_ctree_fd (fp=fp@entry=3, path=path@entry=0x7fffffffe20d "ramdisk/btrfs_fukked.bin", + sb_bytenr=65536, sb_bytenr@entry=0, root_tree_bytenr=root_tree_bytenr@entry=0, flags=flags@entry=OPEN_CTREE_EXCLUSIVE) + at disk-io.c:1199 +#12 0x000000000043d965 in open_ctree_fs_info (filename=0x7fffffffe20d "ramdisk/btrfs_fukked.bin", sb_bytenr=sb_bytenr@entry=0, + root_tree_bytenr=root_tree_bytenr@entry=0, flags=flags@entry=OPEN_CTREE_EXCLUSIVE) at disk-io.c:1231 +#13 0x0000000000427bf5 in cmd_check (argc=1, argv=0x7fffffffdea0) at cmds-check.c:9326 +#14 0x000000000040e5a2 in main (argc=2, argv=0x7fffffffdea0) at btrfs.c:245 + + +valgrind output: + +==32463== Memcheck, a memory error detector +==32463== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. +==32463== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info +==32463== Command: btrfs check ramdisk/btrfs_fukked.bin +==32463== +==32463== Invalid write of size 8 +==32463== at 0x4386FB: btrfs_search_slot (ctree.c:1119) +==32463== by 0x4427F7: UnknownInlinedFun (extent-tree.c:3117) +==32463== by 0x4427F7: btrfs_read_block_groups (extent-tree.c:3167) +==32463== by 0x43D4F2: btrfs_setup_all_roots (disk-io.c:983) +==32463== by 0x43D801: __open_ctree_fd (disk-io.c:1199) +==32463== by 0x43D964: open_ctree_fs_info (disk-io.c:1231) +==32463== by 0x427BF4: cmd_check (cmds-check.c:9326) +==32463== by 0x40E5A1: main (btrfs.c:245) +==32463== Address 0x4c409f0 is 16 bytes after a block of size 144 alloc'd +==32463== at 0x4A08946: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) +==32463== by 0x4427AB: btrfs_read_block_groups (extent-tree.c:3162) +==32463== by 0x43D4F2: btrfs_setup_all_roots (disk-io.c:983) +==32463== by 0x43D801: __open_ctree_fd (disk-io.c:1199) +==32463== by 0x43D964: open_ctree_fs_info (disk-io.c:1231) +==32463== by 0x427BF4: cmd_check (cmds-check.c:9326) +==32463== by 0x40E5A1: main (btrfs.c:245) +==32463== +==32463== Invalid read of size 8 +==32463== at 0x436E70: check_block.part.14 (ctree.c:548) +==32463== by 0x438954: UnknownInlinedFun (kerncompat.h:91) +==32463== by 0x438954: btrfs_search_slot (ctree.c:1120) +==32463== by 0x4427F7: UnknownInlinedFun (extent-tree.c:3117) +==32463== by 0x4427F7: btrfs_read_block_groups (extent-tree.c:3167) +==32463== by 0x43D4F2: btrfs_setup_all_roots (disk-io.c:983) +==32463== by 0x43D801: __open_ctree_fd (disk-io.c:1199) +==32463== by 0x43D964: open_ctree_fs_info (disk-io.c:1231) +==32463== by 0x427BF4: cmd_check (cmds-check.c:9326) +==32463== by 0x40E5A1: main (btrfs.c:245) +==32463== Address 0x4c409f8 is 24 bytes after a block of size 144 in arena "client" +==32463== +==32463== Invalid read of size 4 +==32463== at 0x436E84: UnknownInlinedFun (ctree.h:1605) +==32463== by 0x436E84: UnknownInlinedFun (ctree.h:1612) +==32463== by 0x436E84: check_block.part.14 (ctree.c:550) +==32463== by 0x438954: UnknownInlinedFun (kerncompat.h:91) +==32463== by 0x438954: btrfs_search_slot (ctree.c:1120) +==32463== by 0x4427F7: UnknownInlinedFun (extent-tree.c:3117) +==32463== by 0x4427F7: btrfs_read_block_groups (extent-tree.c:3167) +==32463== by 0x43D4F2: btrfs_setup_all_roots (disk-io.c:983) +==32463== by 0x43D801: __open_ctree_fd (disk-io.c:1199) +==32463== by 0x43D964: open_ctree_fs_info (disk-io.c:1231) +==32463== by 0x427BF4: cmd_check (cmds-check.c:9326) +==32463== by 0x40E5A1: main (btrfs.c:245) +==32463== Address 0x4c409e4 is 4 bytes after a block of size 144 alloc'd +==32463== at 0x4A08946: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) +==32463== by 0x4427AB: btrfs_read_block_groups (extent-tree.c:3162) +==32463== by 0x43D4F2: btrfs_setup_all_roots (disk-io.c:983) +==32463== by 0x43D801: __open_ctree_fd (disk-io.c:1199) +==32463== by 0x43D964: open_ctree_fs_info (disk-io.c:1231) +==32463== by 0x427BF4: cmd_check (cmds-check.c:9326) +==32463== by 0x40E5A1: main (btrfs.c:245) +==32463== +==32463== Invalid read of size 1 +==32463== at 0x4A0B3A0: memcpy@@GLIBC_2.14 (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) +==32463== by 0x436E99: UnknownInlinedFun (ctree.h:1613) +==32463== by 0x436E99: check_block.part.14 (ctree.c:550) +==32463== by 0x438954: UnknownInlinedFun (kerncompat.h:91) +==32463== by 0x438954: btrfs_search_slot (ctree.c:1120) +==32463== by 0x4427F7: UnknownInlinedFun (extent-tree.c:3117) +==32463== by 0x4427F7: btrfs_read_block_groups (extent-tree.c:3167) +==32463== by 0x43D4F2: btrfs_setup_all_roots (disk-io.c:983) +==32463== by 0x43D801: __open_ctree_fd (disk-io.c:1199) +==32463== by 0x43D964: open_ctree_fs_info (disk-io.c:1231) +==32463== by 0x427BF4: cmd_check (cmds-check.c:9326) +==32463== by 0x40E5A1: main (btrfs.c:245) +==32463== Address 0x1b1 is not stack'd, malloc'd or (recently) free'd +==32463== +==32463== +==32463== Process terminating with default action of signal 11 (SIGSEGV) +==32463== Access not within mapped region at address 0x1B1 +==32463== at 0x4A0B3A0: memcpy@@GLIBC_2.14 (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) +==32463== by 0x436E99: UnknownInlinedFun (ctree.h:1613) +==32463== by 0x436E99: check_block.part.14 (ctree.c:550) +==32463== by 0x438954: UnknownInlinedFun (kerncompat.h:91) +==32463== by 0x438954: btrfs_search_slot (ctree.c:1120) +==32463== by 0x4427F7: UnknownInlinedFun (extent-tree.c:3117) +==32463== by 0x4427F7: btrfs_read_block_groups (extent-tree.c:3167) +==32463== by 0x43D4F2: btrfs_setup_all_roots (disk-io.c:983) +==32463== by 0x43D801: __open_ctree_fd (disk-io.c:1199) +==32463== by 0x43D964: open_ctree_fs_info (disk-io.c:1231) +==32463== by 0x427BF4: cmd_check (cmds-check.c:9326) +==32463== by 0x40E5A1: main (btrfs.c:245) diff --git a/tests/fuzz-tests/images/bko-97191-btrfs-image.raw.xz b/tests/fuzz-tests/images/bko-97191-btrfs-image.raw.xz new file mode 100644 index 00000000..b2e48c08 Binary files /dev/null and b/tests/fuzz-tests/images/bko-97191-btrfs-image.raw.xz differ diff --git a/tests/fuzz-tests/images/bko-97271-btrfs-image.raw.txt b/tests/fuzz-tests/images/bko-97271-btrfs-image.raw.txt new file mode 100644 index 00000000..67f20968 --- /dev/null +++ b/tests/fuzz-tests/images/bko-97271-btrfs-image.raw.txt @@ -0,0 +1,54 @@ +URL: https://bugzilla.kernel.org/show_bug.cgi?id=97271 +Lukas Lueg 2015-04-25 20:34:39 UTC + +The attached btrfs-image causes "btrfs check" to write outside of allocated +memory locations and ultimately die due to a segfault. An adjacent heap block's +control structure is overwritten with a `struct extent_buffer *`, which is not +controllable by the user. + +"btrfs version" is v3.19.1. Running "btrfs check" immediately dies with + +*** Error in `btrfs': double free or corruption (!prev): 0x0000000002396ec0 *** +*** Error in `btrfs': malloc(): memory corruption: 0x0000000002396f60 *** + +Debugging with valgrind and gdb gives + +==11670== Invalid write of size 8 +==11670== at 0x4386FB: btrfs_search_slot (ctree.c:1119) +==11670== by 0x44E16E: btrfs_read_chunk_tree (volumes.c:1814) +==11670== by 0x43D654: btrfs_setup_chunk_tree_and_device_map (disk-io.c:1115) +==11670== by 0x43D7D0: __open_ctree_fd (disk-io.c:1190) +==11670== by 0x43D964: open_ctree_fs_info (disk-io.c:1231) +==11670== by 0x427BF4: cmd_check (cmds-check.c:9326) +==11670== by 0x40E5A1: main (btrfs.c:245) +==11670== Address 0x4c3bb98 is 8 bytes after a block of size 144 alloc'd +==11670== at 0x4A08946: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) +==11670== by 0x44E133: btrfs_read_chunk_tree (volumes.c:1801) +==11670== by 0x43D654: btrfs_setup_chunk_tree_and_device_map (disk-io.c:1115) +==11670== by 0x43D7D0: __open_ctree_fd (disk-io.c:1190) +==11670== by 0x43D964: open_ctree_fs_info (disk-io.c:1231) +==11670== by 0x427BF4: cmd_check (cmds-check.c:9326) +==11670== by 0x40E5A1: main (btrfs.c:245) + +Program received signal SIGTRAP, Trace/breakpoint trap. +btrfs_search_slot (trans=trans@entry=0x0, root=root@entry=0x4c36d30, key=key@entry=0xffefff830, p=p@entry=0x4c3bb00, + ins_len=ins_len@entry=0, cow=cow@entry=0) at ctree.c:1119 +1119 p->nodes[level] = b; +(gdb) p p->nodes +$1 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} +(gdb) p p +$2 = (struct btrfs_path *) 0x4c3bb00 +(gdb) p b +$3 = (struct extent_buffer *) 0x4c3a990 + + +The corresponding part in ctree.c:btrfs_search_slot() seems to fail to check if `level` overflows outside of `node`: + +level = btrfs_header_level(b); +... +if (level != btrfs_header_level(b)) + WARN_ON(1); +level = btrfs_header_level(b); +p->nodes[level] = b; // <- Illegal write + +Maybe the repeated calls to btrfs_header_level() were meant to do something once, they seem to be noise. diff --git a/tests/fuzz-tests/images/bko-97271-btrfs-image.raw.xz b/tests/fuzz-tests/images/bko-97271-btrfs-image.raw.xz new file mode 100644 index 00000000..3c79edb5 Binary files /dev/null and b/tests/fuzz-tests/images/bko-97271-btrfs-image.raw.xz differ