kspalaiologos / bzip3

A better and stronger spiritual successor to BZip2.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Use a better BWT construction library or fix libsais.

kspalaiologos opened this issue · comments

Fuzzing with AFL quickly reveals a libsais bug:

==681899==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f96e7ab7860 at pc 0x55dfb3261cbf bp 0x7ffd8a8b4190 sp 0x7ffd8a8b4188
WRITE of size 4 at 0x7f96e7ab7860 thread T0
    #0 0x55dfb3261cbe in libsais_unbwt_calculate_biPSI include/libsais.h:4581
    #1 0x55dfb3261cbe in libsais_unbwt_init_single include/libsais.h:4610
    #2 0x55dfb32bb40e in libsais_unbwt_core include/libsais.h:5158
    #3 0x55dfb32bb40e in libsais_unbwt_main include/libsais.h:5182
    #4 0x55dfb32bb40e in libsais_unbwt_aux include/libsais.h:5225
    #5 0x55dfb32bb40e in libsais_unbwt include/libsais.h:5255
    #6 0x55dfb32bb40e in bz3_decode_block src/libbz3.c:679
    #7 0x55dfb32c0da6 in bz3_decompress src/libbz3.c:882
    #8 0x55dfb323a06e in main examples/fuzz.c:33
    #9 0x7f96e7029209 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #10 0x7f96e70292bb in __libc_start_main_impl ../csu/libc-start.c:389
    #11 0x55dfb323a230 in _start (/home/palaiologos/Desktop/workspace/bzip3/examples/fd+0xa5230)

0x7f96e7ab7860 is located 88 bytes to the right of 266248-byte region [0x7f96e7a76800,0x7f96e7ab7808)
allocated by thread T0 here:
    #0 0x7f96e7cb89cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x55dfb32a6ba8 in bz3_new src/libbz3.c:499

Attached example (decompress using examples/fuzz case.txt): case.txt

Knowing the upstream maintainer's attitude towards soundness errors in his library, we might have to fix it ourselves.

bzip3/include/libsais.h

Lines 4574 to 4583 in 1f8165b

for (i += 1; i <= j; ++i) {
fast_uint_t c = T[i - 1];
fast_uint_t p = bucket1[c]++;
fast_sint_t t = (fast_sint_t)(index - p);
if (t != 0) {
fast_uint_t w = (((fast_uint_t)T[p + (fast_uint_t)(t >> ((sizeof(fast_sint_t) * 8) - 1))]) << 8) + c;
P[bucket2[w]++] = (sa_uint_t)i;
}
}

is the culprit of the issue; it seems like the index into P causes an array out of bounds access on P.

Tentatively fixed by bfa5bf8