Closed Dr-Emann closed 5 years ago
Possibly related crash: Base64'd archive:
aHNxcwEAAADZhl5dABAAAAAAAAABAAwAywECAAQAAAAAAAAAAAAAAKYAAAAAAAAAngAAAAAAAAD/
/////////2AAAAAAAAAAggAAAAAAAACCAAAAAAAAAIwAAAAAAAAAIIAJAP0BAAABALKGXl0BAAAA
AAAAAAIAAAADAP////8AAAiAAAAAAAAAAACCAAAAAAAAAAiA6QMAAOsDAACUAAAAAAAAAA==
ASAN:
=================================================================
==2198==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf5300771 at pc 0x081085bb bp 0xff8b3308 sp 0xff8b2ee0
WRITE of size 16 at 0xf5300771 thread T0
#0 0x81085ba in __asan_memcpy (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x81085ba)
#1 0x8155c48 in read_inode_file_ext /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:141:14
#2 0x8155c48 in meta_reader_read_inode /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:238
#3 0x81505e6 in deserialize_fstree /home/dremann/Development/squashfs-tools-ng/lib/sqfs/deserialize_fstree.c:232:9
#4 0x814d26c in sqfs_reader_open /home/dremann/Development/squashfs-tools-ng/lib/sqfs/sqfs_reader.c:46:6
#5 0x813a4fa in main /home/dremann/Development/squashfs-tools-ng/unpack/rdsquashfs.c:33:6
#6 0xf7c3b750 in __libc_start_main (/lib32/libc.so.6+0x1e750)
#7 0x8062561 in _start (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x8062561)
0xf5300771 is located 0 bytes to the right of 1-byte region [0xf5300770,0xf5300771)
allocated by thread T0 here:
#0 0x8109575 in calloc (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x8109575)
#1 0x8155bfc in read_inode_file_ext /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:135:8
#2 0x8155bfc in meta_reader_read_inode /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:238
#3 0x81505e6 in deserialize_fstree /home/dremann/Development/squashfs-tools-ng/lib/sqfs/deserialize_fstree.c:232:9
#4 0x814d26c in sqfs_reader_open /home/dremann/Development/squashfs-tools-ng/lib/sqfs/sqfs_reader.c:46:6
SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x81085ba) in __asan_memcpy
Shadow bytes around the buggy address:
0x3ea60090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea600a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea600b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea600c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea600d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x3ea600e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[01]fa
0x3ea600f0: fa fa fd fa fa fa 00 fa fa fa fa fa fa fa fa fa
0x3ea60100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea60110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea60120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea60130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==2198==ABORTING
Another possible one that looks about the same:
Base64 archive:
aHNxcwEAAADZhl5dABAAAAAAAAABAAwAywECAAQAAAAAAAAAAAAAAKYAAAAAAAAAngAAAAAAAAD/
/////////2AAAAAAAAAAggAAAAAAAACCAAAAAAAAAIwAAAAAAAAAIIAJAP0BAAABALKCAAAAAAAA
AIwAAAAAAAAAIP////8BAAABALKGXl0AEAAAAAAAAAAAAAiA6QMAAOsDAACUAAAAAAAAAA==
ASAN:
=================================================================
==21581==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf5300778 at pc 0x081085bb bp 0xffbe7da8 sp 0xffbe7980
WRITE of size 16 at 0xf5300778 thread T0
#0 0x81085ba in __asan_memcpy (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x81085ba)
#1 0x8155c48 in read_inode_file_ext /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:141:14
#2 0x8155c48 in meta_reader_read_inode /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:238
#3 0x81505e6 in deserialize_fstree /home/dremann/Development/squashfs-tools-ng/lib/sqfs/deserialize_fstree.c:232:9
#4 0x814d26c in sqfs_reader_open /home/dremann/Development/squashfs-tools-ng/lib/sqfs/sqfs_reader.c:46:6
#5 0x813a4fa in main /home/dremann/Development/squashfs-tools-ng/unpack/rdsquashfs.c:33:6
#6 0xf7bfc750 in __libc_start_main (/lib32/libc.so.6+0x1e750)
#7 0x8062561 in _start (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x8062561)
0xf5300778 is located 0 bytes to the right of 8-byte region [0xf5300770,0xf5300778)
allocated by thread T0 here:
#0 0x8109575 in calloc (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x8109575)
#1 0x8155bfc in read_inode_file_ext /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:135:8
#2 0x8155bfc in meta_reader_read_inode /home/dremann/Development/squashfs-tools-ng/lib/sqfs/read_inode.c:238
#3 0x81505e6 in deserialize_fstree /home/dremann/Development/squashfs-tools-ng/lib/sqfs/deserialize_fstree.c:232:9
#4 0x814d26c in sqfs_reader_open /home/dremann/Development/squashfs-tools-ng/lib/sqfs/sqfs_reader.c:46:6
SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/dremann/Development/squashfs-tools-ng/rdsquashfs+0x81085ba) in __asan_memcpy
Shadow bytes around the buggy address:
0x3ea60090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea600a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea600b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea600c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea600d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x3ea600e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa 00[fa]
0x3ea600f0: fa fa fd fa fa fa 00 fa fa fa fa fa fa fa fa fa
0x3ea60100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea60110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea60120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x3ea60130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==21581==ABORTING
Again, thanks for all the effort!
The issue here turns out to be unsigned integer overflows. The code turns a lot of on-disk data structures into structs with flexible array members and contains the pattern type *x = calloc(1, sizeof(*x) + foo);
all over the place, where foo
is read from disk and thus attacker controlled.
If foo
happens to be the same size as size_t, this can easily produce an overflow with (in some cases) the total sum being less than the size of even the base struct.
I guess #14 is also related, but I haven't looked at it in more detail yet.
I already pushed a few commits that fix a few places that could be found with a simple grep and where straight forward to replace. I'm still busy replacing the not so straight forward cases and more thoroughly reviewing all code that does size accounting.
Things are looking pretty good: coming up on 24 hours fuzzing with no crashes under AFL, compiled with ASAN, using commit fa893f8.
Base 64 encoded squashfs archive:
Compiled master with ASAN enabled for AFL, using 32bit
Running
rdsquashfs -d bad.squashfs
outputs the following from ASAN: