New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multiple concurrency UAF bug between zpaq_decompress_buf() and clear_rulist() function
#206
Comments
|
Totally broken file.I use a validation function prior to decompress or test. It will catch this broken file before it even starts. Interesting academic exercise, but not worth it, IMHO. |
|
Actually, the uploaded file is a well-crafted input. Given an illegal input file, concurrency use-after-free may occur. Because once the program failed to read chunk_bytes size in runzip_chunk function, the program will release the resources (i.e., free) and terminate. However, other threads still could access the released resources before termination. |
|
All decompress functions perform the same way. As @ckolivas likes to say, patches welcome. |
|
Fixed in 4b39421 , thanks. |
Dear all,
Our tool report that there would be multiple concurrency use-after-free between
zpaq_decompress_buf()function andclear_rulist()function, in the newest master branch 465afe8.Brief Explanation
The related code simplified from
stream.candrunzip.care shown as follow:Both thread T0 and thread T1 operate on a shared variable
ucthread(i.e., T0 dealloc the a ucthread throughdealloc(sinfo->ucthreads);, and T1 use the ucthread in all statementsif (unlikely(dlen != ucthread->u_len)),dealloc(ucthread->s_buf);, anducthread->s_buf = c_buf;).However, a use-after-free can occur if the deallocation of ucthread before the use of ucthread.
For example, the following three thread interleaving can trigger three different UAFs:
Interleaving (a)
Interleaving (b)
Interleaving (c)
Reproduce through delay injection
To reproduce those use-after-free errors, we can insert two delays (e.g.,
sleep(1)) into the original source code.For example, to reproduce interleaving (a) as mentioned earlier, you can insert a delay before
dealloc(sinfo->ucthreads);statement in function insteam.c, and also a delay after, as shown as follows.compile the program:
Download the testcase (I upload the POC here, please unzip first).
POC.zip
Run with the testcase with the following command:
Then, you will see the use-after-free bug report. Here is the trace reported by ASAN:
================================================================= ==33325==ERROR: AddressSanitizer: heap-use-after-free on address 0x61d0000000e8 at pc 0x000000512b00 bp 0x7f9a30bfdb10 sp 0x7f9a30bfdb08 READ of size 8 at 0x61d0000000e8 thread T3 #0 0x512aff in zpaq_decompress_buf /workdir/lrzip/stream.c:449:6 #1 0x510381 in ucompthread /workdir/lrzip/stream.c:1554:11 #2 0x7f9a3541b6da in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76da) #3 0x7f9a3479771e in clone (/lib/x86_64-linux-gnu/libc.so.6+0x12171e) 0x61d0000000e8 is located 104 bytes inside of 2400-byte region [0x61d000000080,0x61d0000009e0) freed by thread T0 here: #0 0x494e1d in free /home/brian/src/final/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:123:3 #1 0x4faa0d in clear_rulist /workdir/lrzip/runzip.c:255:3 #2 0x4f7ab2 in runzip_chunk /workdir/lrzip/runzip.c:384:2 #3 0x4f4aae in runzip_fd /workdir/lrzip/runzip.c:404:7 #4 0x4d84ce in decompress_file /workdir/lrzip/lrzip.c:845:6 #5 0x4cb98b in main /workdir/lrzip/main.c:706:4 #6 0x7f9a34697bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6) previously allocated by thread T0 here: #0 0x495212 in calloc /home/brian/src/final/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:154:3 #1 0x5003e1 in open_stream_in /workdir/lrzip/stream.c:1084:33 #2 0x4f6fa5 in runzip_chunk /workdir/lrzip/runzip.c:322:7 #3 0x4f4aae in runzip_fd /workdir/lrzip/runzip.c:404:7 #4 0x4d84ce in decompress_file /workdir/lrzip/lrzip.c:845:6 #5 0x4cb98b in main /workdir/lrzip/main.c:706:4 #6 0x7f9a34697bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6) Thread T3 created by T0 here: #0 0x47fe4a in pthread_create /home/brian/src/final/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp:214:3 #1 0x4fbbd0 in create_pthread /workdir/lrzip/stream.c:125:6 #2 0x507033 in fill_buffer /workdir/lrzip/stream.c:1713:6 #3 0x504184 in read_stream /workdir/lrzip/stream.c:1800:8 #4 0x4f9c88 in unzip_literal /workdir/lrzip/runzip.c:162:16 #5 0x4f731c in runzip_chunk /workdir/lrzip/runzip.c:338:9 #6 0x4f4aae in runzip_fd /workdir/lrzip/runzip.c:404:7 #7 0x4d84ce in decompress_file /workdir/lrzip/lrzip.c:845:6 #8 0x4cb98b in main /workdir/lrzip/main.c:706:4 #9 0x7f9a34697bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6) SUMMARY: AddressSanitizer: heap-use-after-free /workdir/lrzip/stream.c:449:6 in zpaq_decompress_buf Shadow bytes around the buggy address: 0x0c3a7fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c3a7fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c3a7fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c3a7fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c3a7fff8000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x0c3a7fff8010: fd fd fd fd fd fd fd fd fd fd fd fd fd[fd]fd fd 0x0c3a7fff8020: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c3a7fff8030: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c3a7fff8040: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c3a7fff8050: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c3a7fff8060: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 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 ==33325==ABORTINGI'm not sure if these use-after-free bugs could cause serious harm. I hope you can check whether it is necessary to fix these bugs.
Thanks.
The text was updated successfully, but these errors were encountered: