Open huanglei3 opened 1 year ago
Try this for lrzip
:
diff --git a/stream.c b/stream.c
index 7093ca9..87597c4 100644
--- a/stream.c
+++ b/stream.c
@@ -1220,11 +1220,11 @@ again:
print_err("Wrong password?\n");
goto failed;
}
- if (unlikely(v1)) {
+ if (unlikely(v1 < 1)) {
print_err("Unexpected initial c_len %lld in streams %lld\n", v1, v2);
goto failed;
}
- if (unlikely(v2)) {
+ if (unlikely(v2 < 1)) {
print_err("Unexpected initial u_len %lld in streams\n", v2);
goto failed;
}
This issue seems to be CVE-2023-39741
@carnil , The actual bug is in ZPAQ. The SDK used here is old. The last SDK (before Matt Mahoney retired), 7.15 has more robust error checking. Using @huanglei3 POC file...
There's a limit to how much error prevention can be done. If you examine the code in stream.c
and other files, you will see exhaustive data checks. a solution is either to update the zpaq SDK like I did with lrzip-next
or examine the libzpaq.cpp
file at line 1311 and 1208. Or you can try the preventative fix posted above.
I get tired of these attempts to make a program fail. I'd rather people would try and make the programs better. Contribute code.
Fill_buffer stream 1 c_len 981 u_len 6036 last_head 1019
Starting thread 1 to decompress 981 bytes from stream 1
Reading ucomp header at 1048
Fill_buffer stream 1 c_len 0 u_len 0 last_head 0
Skipping empty match block
ZPAQ 2:21%
Thread 3 "lrzip" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7a1e6c0 (LWP 8576)]
libzpaq::PostProcessor::write (this=0x7ffff7a1dc70, c=0) at libzpaq/libzpaq.cpp:1208
1208 z.header[z.hend++]=c; // one byte of pcomp
(gdb) info stack
#0 libzpaq::PostProcessor::write (this=0x7ffff7a1dc70, c=0) at libzpaq/libzpaq.cpp:1208
#1 0x0000555555582ce4 in libzpaq::Decompresser::decompress (this=0x7ffff7a02b60, n=-1) at libzpaq/libzpaq.cpp:1311
#2 0x0000555555582f15 in libzpaq::decompress (in=0x7ffff7a1ddc0, out=0x7ffff7a1dda0) at libzpaq/libzpaq.cpp:1366
#3 0x000055555557a729 in zpaq_decompress (s_buf=0x7ffff0000b70 "", d_len=0x7ffff7a1de68, c_buf=0x5555555ca160 "zPQ\001", <incomplete sequence \304>, c_len=697, msgout=0x7ffff7bf2760 <_IO_2_1_stdout_>, progress=true,
thread=1) at libzpaq/libzpaq.h:539
#4 0x000055555556d063 in zpaq_decompress_buf (control=0x5555555aed40 <local_control>, ucthread=0x5555555c85e0, thread=1) at stream.c:446
#5 0x000055555557190e in ucompthread (data=0x0) at stream.c:1566
#6 0x00007ffff7aa8044 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#7 0x00007ffff7b285fc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
Using SDK 7.15 from lrzip-next
Fill_buffer stream 1 c_len 0 u_len 0 last_head 0
Skipping empty match block
ZPAQ Error: Empty PCOMP
[Inferior 1 (process 13034) exited with code 01]
project : lrzip 0.651
exec : ./lrzip -t file
Decompressing...
==641214==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6140000001ec at pc 0x0000005260ac bp 0x7f4b526e35d0 sp 0x7f4b526e35c8 WRITE of size 1 at 0x6140000001ec thread T2
0 0x5260ab in libzpaq::PostProcessor::write(int) /home/cc/lrzip/obj-afl/../libzpaq/libzpaq.cpp:1208:25
0x6140000001ec is located 0 bytes to the right of 428-byte region [0x614000000040,0x6140000001ec) allocated by thread T2 here:
0 0x495f42 in calloc (/home/cc/lrzip/obj-afl/lrzip+0x495f42)
Thread T2 created by T0 here:
0 0x480b7a in pthread_create (/home/cc/lrzip/obj-afl/lrzip+0x480b7a)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/cc/lrzip/obj-afl/../libzpaq/libzpaq.cpp:1208:25 in libzpaq::PostProcessor::write(int) Shadow bytes around the buggy address: 0x0c287fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c287fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c287fff8000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 0x0c287fff8010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c287fff8020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c287fff8030: 00 00 00 00 00 00 00 00 00 00 00 00 00[04]fa fa 0x0c287fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c287fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c287fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c287fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c287fff8080: 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 ==641214==ABORTING poc.zip
and you can download it from the link: poc:https://github.com/huanglei3/lrzip_poc/blob/main/lrzip_heap_overflow/overflow