Skip to content

Concurrency null-pointer-dereference in ucompthread() of stream.c #263

@ZIllR0

Description

@ZIllR0

Hi guys,

We also found a concurrency npd in ucompthread function. I think this has similarities to the #262 I submitted earlier, but I’m not sure if it’s actually the same root cause. I hope you can check it. This vulnerability also exists in the latest version of the master branch 1242aec.

Reproduction

Although our tools can trigger this vulnerability, developers may improve the chances of reproducing the concurrency NPD by introducing multiple delays, as shown below:

// in lrzip.c, insert a delay after "dealloc(sinfo->ucthreads)" to extend npd window.
static void clear_rulist(rzip_control *control)
{
	while (control->ruhead) {
		struct runzip_node *node = control->ruhead;
		struct stream_info *sinfo = node->sinfo;

		dealloc(sinfo->ucthreads);
		sleep(1);   // delay here!!!
		dealloc(node->pthreads);
		dealloc(sinfo->s);
		dealloc(sinfo);
		control->ruhead = node->prev;
		dealloc(node);
	}
}
// in stream.c, insert a delay before "struct uncomp_thread *uci = &sts->sinfo->ucthreads[i]" to ensure the dereference occurs after the null assignment.
static void *ucompthread(void *data)
{
	stream_thread_struct *sts = data;
	rzip_control *control = sts->control;
	int waited = 0, ret = 0, i = sts->i;
	sleep(1);    // delay here!!!
	struct uncomp_thread *uci = &sts->sinfo->ucthreads[i];
        ...
}
// in lrzip.c, insert a delay after 'clear_rulist(control)' to guarantee a full ASAN report is generated.
bool decompress_file(rzip_control *control)
{
    ...
	if (unlikely(runzip_fd(control, fd_in, fd_hist, expected_size) < 0)) {
		clear_rulist(control);
		sleep(1);  // delay here!!!
		return false;
	}
    ...

}

Compile Command:

./autogen.sh
CC="gcc -fsanitize=address -fno-omit-frame-pointer -g -O0" CXX="g++ -fsanitize=address -fno-omit-frame-pointer -g -O0" ./configure --enable-static-bin --disable-shared
make -j4

PoC file:

A crafted PoC is available here, please unzip first.

Run Command:

./lrzip -t -p2 ./PoC_NPD

And there is the ASAN report:

AddressSanitizer:DEADLYSIGNAL
=================================================================
==17356==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000080 (pc 0x556a62c35ae9 bp 0x7fa73678add0 sp 0x7fa73678ac40 T3)
==17356==The signal is caused by a READ memory access.
==17356==Hint: address points to the zero page.
    #0 0x556a62c35ae9 in ucompthread /home/ziiiro/work/eval/vul_repro/lrzip/stream.c:1551
    #1 0x7fa739baeac2 in start_thread nptl/pthread_create.c:442
    #2 0x7fa739c4084f  (/lib/x86_64-linux-gnu/libc.so.6+0x12684f)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ziiiro/work/eval/vul_repro/lrzip/stream.c:1551 in ucompthread
Thread T3 created by T0 here:
    #0 0x7fa73a140685 in __interceptor_pthread_create ../../../../src/libsanitizer/asan/asan_interceptors.cpp:216
    #1 0x556a62c3e8a6 in create_pthread /home/ziiiro/work/eval/vul_repro/lrzip/stream.c:125
    #2 0x556a62c3e8a6 in fill_buffer /home/ziiiro/work/eval/vul_repro/lrzip/stream.c:1725
    #3 0x556a62c3e8a6 in read_stream /home/ziiiro/work/eval/vul_repro/lrzip/stream.c:1811
    #4 0x556a62c31361 in unzip_literal /home/ziiiro/work/eval/vul_repro/lrzip/runzip.c:162
    #5 0x556a62c31361 in runzip_chunk /home/ziiiro/work/eval/vul_repro/lrzip/runzip.c:325
    #6 0x556a62c31361 in runzip_fd /home/ziiiro/work/eval/vul_repro/lrzip/runzip.c:387
    #7 0x556a62c1ffe3 in decompress_file /home/ziiiro/work/eval/vul_repro/lrzip/lrzip.c:952
    #8 0x556a62c16284 in main /home/ziiiro/work/eval/vul_repro/lrzip/main.c:720
    #9 0x7fa739b43d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions