ckolivas / lrzip

Long Range Zip
http://lrzip.kolivas.org
GNU General Public License v2.0
615 stars 76 forks source link

BUG heap_buffer_overflow in read_1g on release version 0.631 #156

Closed hfzhang31 closed 3 years ago

hfzhang31 commented 4 years ago

On lrzip 0.631, these is a heap_over_flow crash in read_1g

Here is the file triggering the crash. test5.zip (this file is generated using afl)

➜ lrzip-0.631 ./lrzip -vv -d test5 -o t5 The following options are in effect for this DECOMPRESSION. Threading is ENABLED. Number of CPUs detected: 48 Detected 270371979264 bytes ram Compression level 7 Nice Value: 19 Show Progress Max Verbose Output Filename Specified: t5 Temporary Directory set as: ./ Output filename is: t5 Malloced 90123993088 for tmp_outbuf Detected lrzip version 0.6 file. MD5 being used for integrity testing. Decompressing... Reading chunk_bytes at 24 Expected size: 12 Chunk byte width: 1 Reading eof flag at 25 EOF: 1 Reading expected chunksize at 26 Chunk size: 0 Reading stream 0 header at 28 Reading stream 1 header at 32 Reading ucomp header at 36 Fill_buffer stream 0 c_len 26 u_len 10 last_head 0

AddressSanitizer outputs as follows:

================================================================= ==86605==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000007a at pc 0x7f5c6530f0ae bp 0x7ffe518295a0 sp 0x7ffe51828d48 WRITE of size 26 at 0x60200000007a thread T0

0 0x7f5c6530f0ad (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x4e0ad)

#1 0x55d48bff7eb6 in read /usr/include/x86_64-linux-gnu/bits/unistd.h:44
#2 0x55d48bff7eb6 in read_1g /home/yongheng/z_fuzz/raw/lrzip-0.631/stream.c:731
#3 0x55d48bff8120 in read_buf /home/yongheng/z_fuzz/raw/lrzip-0.631/stream.c:774
#4 0x55d48bffe1de in fill_buffer /home/yongheng/z_fuzz/raw/lrzip-0.631/stream.c:1648
#5 0x55d48bffe1de in read_stream /home/yongheng/z_fuzz/raw/lrzip-0.631/stream.c:1755
#6 0x55d48bff1cb1 in read_u8 /home/yongheng/z_fuzz/raw/lrzip-0.631/runzip.c:55
#7 0x55d48bff1cb1 in read_header /home/yongheng/z_fuzz/raw/lrzip-0.631/runzip.c:144
#8 0x55d48bff1cb1 in runzip_chunk /home/yongheng/z_fuzz/raw/lrzip-0.631/runzip.c:314
#9 0x55d48bff1cb1 in runzip_fd /home/yongheng/z_fuzz/raw/lrzip-0.631/runzip.c:382
#10 0x55d48bfe2dc1 in decompress_file /home/yongheng/z_fuzz/raw/lrzip-0.631/lrzip.c:826
#11 0x55d48bfda834 in main /home/yongheng/z_fuzz/raw/lrzip-0.631/main.c:669
#12 0x7f5c63d44b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#13 0x55d48bfdc3d9 in _start (/home/yongheng/z_fuzz/raw/lrzip-0.631/lrzip+0x173d9)

0x60200000007a is located 0 bytes to the right of 10-byte region [0x602000000070,0x60200000007a) allocated by thread T0 here:

0 0x7f5c6539fb40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)

#1 0x55d48bffe174 in fill_buffer /home/yongheng/z_fuzz/raw/lrzip-0.631/stream.c:1643
#2 0x55d48bffe174 in read_stream /home/yongheng/z_fuzz/raw/lrzip-0.631/stream.c:1755

SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x4e0ad) Shadow bytes around the buggy address: 0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c047fff8000: fa fa 05 fa fa fa 03 fa fa fa 04 fa fa fa 00[02] 0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8050: 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 ==86605==ABORTING

pete4abw commented 4 years ago

Please, this is unhelpful. What was the file you were compressing? What were the lrzip command line options? Where is the output summary? Always use lrzip -vv. Your zip file is the partially compressed file.

hfzhang31 commented 4 years ago

The required information has been attached. The file 'test5' is not generated by compressing a raw file. It is generated by afl.

pete4abw commented 4 years ago

Test 5 is a broken lrz file. Your command line would not work based on a recent bug uncovered yesterday, #155 I can't help unless you show how you compressed it along with the actual test5 file.. Looks like you tried to use the -l option. I created an lrz file using a file containing only testcontent, a 12 byte file! I compressed it and decompressed it, tested it and showed info with no problem.

peter@tommyv:/tmp$ lrzip.631 -lf test6
Using configuration file /home/peter/.lrzip/lrzip.conf
The following options are in effect for this COMPRESSION.
Threading is ENABLED. Number of CPUs detected: 8
Detected 16567324672 bytes ram
Compression level 7
Nice Value: 19
Show Progress
Verbose
Overwrite Files
Temporary Directory set as: ./
Compression mode is: LZO
Heuristically Computed Compression Window: 105 = 10500MB
Output filename is: test6.lrz
File size: 12
Will take 1 pass
Beginning rzip pre-processing phase
MD5: 42ed9fb3563d8e9c7bb522be443033f4
test6 - Compression Ratio: 0.148. Average Compression Speed:  0.000MB/s.
Total time: 00:00:00.05

peter@tommyv:/tmp$ lrzip.631 -t test6.lrz
Using configuration file /home/peter/.lrzip/lrzip.conf
Threading is ENABLED. Number of CPUs detected: 8
Detected 16567324672 bytes ram
Compression level 7
Nice Value: 19
Show Progress
Verbose
Test file integrity
Temporary Directory set as: ./
Detected lrzip version 0.6 file.
MD5 being used for integrity testing.
Decompressing...
100%      12.00 /     12.00 
Average DeCompression Speed:  0.000MB/s
MD5: 42ed9fb3563d8e9c7bb522be443033f4
[OK] - 12 bytes                                
Total time: 00:00:00.05

peter@tommyv:/tmp$ lrzip.631 -i test6.lrz
Using configuration file /home/peter/.lrzip/lrzip.conf
Detected lrzip version 0.6 file.
Rzip chunk 1:
Chunk byte width: 1
Stream: 0
Block   Comp    Percent Size
1       none    100.0%  10 / 10
Stream: 1
Block   Comp    Percent Size
1       none    100.0%  12 / 12
Rzip compression: 183.3% 22 / 12
Back end compression: 100.0% 22 / 22
Overall compression: 183.3% 22 / 12
test6.lrz:
lrzip version: 0.6 file
Compression: rzip alone
Decompressed file size: 12
Compressed file size: 81
Compression ratio: 0.148
MD5 used for integrity testing
MD5: 42ed9fb3563d8e9c7bb522be443033f4

Sorry. As has been discussed before, using lrzip for small files is not beneficial. Make sure you pull the most current patches to lrzip. This is not worth pursuing. On a practical note, lrzip is an extremely effective compression program. The lrz files generated will be corrupted by intentional editing or modification. See the magic.header.txt file for more info.

hfzhang31 commented 4 years ago

My command line is "./lrzip -vv -d test5 -o t5".

I'm a security researcher. I'm fuzzing lrzip with afl (American fuzzy lop) and find that "test5" can trigger a crash when lrzip tries to decompress it.

The file "test5" is generated by afl. It is not a normal lrz file. As you said it is broken. Maybe it will be better if lrzip can check the validity of the received file. If the file is broken, lrzip stops decompressing it and outputs warning information to remind the user as other compression programs do. But now the broken file leads to heap_buffer_overflow and lrzip exits abnormally.

pete4abw commented 4 years ago

You are welcome to submit patches for this.

ckolivas commented 3 years ago

Fixed in git master.