pete4abw / lrzip-next

Long Range Zip. Updated and Enhanced version of ckolivas' lrzip project. Lots of new features. Better compression. Actively maintained.
https://github.com/pete4abw/lrzip-next
GNU General Public License v2.0
50 stars 10 forks source link

Read zero page memory #132

Closed huanglei3 closed 1 year ago

huanglei3 commented 1 year ago

lrzip-next Version

lzma 23.01(default)

lrzip-next command line

./lrzip-next -vvt file

What happened?

./lrzip-next -vvt poc The following options are in effect for this INTEGRITY TEST. Threading is ENABLED. Number of CPUs detected: 4 Detected 8,287,764,480 bytes ram Nice Value: 19 Show Progress Max Verbose Test file integrity Temporary Directory set as: /tmp/ Malloced 2,762,588,160 for tmp_outbuf Detected lrzip version 0.6 file. MD5 being used for integrity testing. Validating file for consistency...[OK] Detected lrzip version 0.6 file. Decompressing...

Reading chunk_bytes at 24 Expected size: 8,324,128 Chunk byte width: 2 Reading eof flag at 25 EOF: 1 Reading expected chunksize at 26 Chunk size: 4,096 Reading stream 0 header at 29 Reading stream 1 header at 36 Reading ucomp header at 43 Fill_buffer stream 0 c_len 2 u_len 10 last_head 0 Starting thread 0 to decompress 2 bytes from stream 0 AddressSanitizer:DEADLYSIGNAL

==3820161==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x7f367294d769 bp 0x000000000002 sp 0x7f35c9cee600 T1) ==3820161==The signal is caused by a READ memory access. ==3820161==Hint: address points to the zero page.

0 0x7f367294d768 in bz3_decode_block src/libbz3.c:619

#1 0x5647df109fe8 in bzip3_decompress_buf /home/tanzheng/fuzz_zip_next/lrzip-next/src/stream.c:632
#2 0x5647df109fe8 in ucompthread /home/tanzheng/fuzz_zip_next/lrzip-next/src/stream.c:1918
#3 0x7f367280e608 in start_thread /build/glibc-SzIz7B/glibc-2.31/nptl/pthread_create.c:477
#4 0x7f36723e5132 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x11f132)

AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV src/libbz3.c:619 in bz3_decode_block Thread T1 created by T0 here:

0 0x7f3672ad7815 in __interceptor_pthread_create ../../../../src/libsanitizer/asan/asan_interceptors.cc:208

#1 0x5647df10edb9 in create_pthread /home/tanzheng/fuzz_zip_next/lrzip-next/src/stream.c:145

==3820161==ABORTING

What was expected behavior?

work well

Steps to reproduce

1.install bzip3 2.install lrzip-next 3.exec:./lrzip-next -vvt poc

Relevant log output

No response

Please provide system details

OS Distro: Kernel Version (uname -a): Linux ubuntu 5.15.0-78-generic #85~20.04.1-Ubuntu SMP Mon Jul 17 09:42:39 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux System ram (free -h): total used free shared buff/cache available Mem: 7.7Gi 4.8Gi 546Mi 4.0Mi 2.4Gi 2.6Gi Swap: 2.0Gi 1.0Mi 2.0Gi

Additional Context

you can download poc file from this link : https://github.com/huanglei3/lrzip-next-poc/tree/main

pete4abw commented 1 year ago

While I normally do not like to deal with files that lrzip-next did not create, this bug was interesting. The macro unlikely(v1) and unlikely(v2) macros did not function as predicted. This fix deals with your issue. We struggled over the years with protecting against bad data and this is one more fix...

diff --git a/src/stream.c b/src/stream.c
index 9d74383..00dd660 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -1491,11 +1491,12 @@ again:
                                print_err("Wrong password?\n");
                        goto failed;
                }
-               if (unlikely(v1)) {
+               /* protect again 0 length c_ and u_ len */
+               if (v1 < 1) {
                        print_err("Unexpected initial c_len %'"PRId64" in streams %'"PRId64"\n", v1, v2);
                        goto failed;
                }
-               if (unlikely(v2)) {
+               if (v2 < 1) {
                        print_err("Unexpected initial u_len %'"PRId64" in streams\n", v2);
                        goto failed;
                }