kspalaiologos / bzip3

A better and stronger spiritual successor to BZip2.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

AddressSanitizer: heap-buffer-overflow

tianmai1 opened this issue · comments

An error occurred ./fuzz crash001
In version 1.3.1
`==115574==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f50c8f8e41c at pc 0x55d36b2a7493 bp 0x7ffeae5cabc0 sp 0x7ffeae5cabb0
WRITE of size 4 at 0x7f50c8f8e41c thread T0
#0 0x55d36b2a7492 in libsais_unbwt_calculate_biPSI include/libsais.h:4587
#1 0x55d36b2a7492 in libsais_unbwt_init_single include/libsais.h:4616
#2 0x55d36b2c972b in libsais_unbwt_core include/libsais.h:5164
#3 0x55d36b2c972b in libsais_unbwt_main include/libsais.h:5189
#4 0x55d36b2c972b in libsais_unbwt_aux include/libsais.h:5231
#5 0x55d36b2c972b in libsais_unbwt include/libsais.h:5261
#6 0x55d36b2c972b in bz3_decode_block src/libbz3.c:694
#7 0x55d36b2ce116 in bz3_decompress src/libbz3.c:903
#8 0x55d36b272b64 in main examples/fuzz.c:43
#9 0x7f50c6dd9c86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86)
#10 0x55d36b272ce9 in _start (/home/tianmai/workspace/bzip3-1.31/examples/fuzz_asan+0x68ce9)

0x7f50c8f8e41c is located 1564 bytes to the right of 292352-byte region [0x7f50c8f46800,0x7f50c8f8de00)
allocated by thread T0 here:
#0 0x7f50c7fa8b40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)
#1 0x55d36b2ba37e in bz3_new src/libbz3.c:512

SUMMARY: AddressSanitizer: heap-buffer-overflow include/libsais.h:4587 in libsais_unbwt_calculate_biPSI
Shadow bytes around the buggy address:
0x0fea991e9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fea991e9c40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fea991e9c50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fea991e9c60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fea991e9c70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0fea991e9c80: fa fa fa[fa]fa fa fa fa fa fa fa fa fa fa fa fa
0x0fea991e9c90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fea991e9ca0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fea991e9cb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fea991e9cc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fea991e9cd0: 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
==115574==ABORTING
`
crash.zip

The crash appears to occur in the libsais library. I have just verified that the SAIS array, input and output are of the correct sizes and further the temporary array has also been zeroed. I don't think that this crash is bzip3's fault.

A debugging session log:

I set a breakpoint just before the crash, verified that sais_array is correctly initialised, that it has the correct size with relation to the source block size. I have also made sure that the index is correct. Before continuing I have zeroed the SAIS array per the recommendation of the library author. This has not solved the issue, hence the problem is not within the code I wrote bzip3 myself. Please consider reporting this issue to libsais instead.

Breakpoint 1, bz3_decode_block (state=0x604000000010, buffer=0x631000028800 "", data_size=6, orig_size=2654)
    at src/libbz3.c:694
694         if (libsais_unbwt(b1, b2, state->sais_array, size_src, NULL, bwt_idx) < 0) {
(gdb) p state->sais_array
$1 = (s32 *) 0x7ffffab11800
(gdb) p (int) malloc_usable_size(state->sais_array)
$2 = 292352
(gdb) p (int) size_src
$3 = 73821
(gdb) p 4 * 73821
$4 = 295284
(gdb) p bwt_idx
$5 = 32
(gdb) p b1
$6 = (u8 *) 0x631000014800 "\275\257U\030O\232KUt\246i\"@j\275\246\251\206\231\204b\211\251{\206\203U\241\214witft\336ܩ\036\333\374\062\342wAE\030\b\315&t\314\315&\250ӻD\211\226\251'.\364N\234Q\fGN&@#\"h#v\214v;d\226\023}\017xc@|\245(\251oC\372\062\364t\362\366m\373\b\362\344͓t\222C̝\022i\030o\363c(\r/\346#\367\214#\334\376\364'\244\"9*\367Π#\364\341&'#\272@\360s\340\246\350\363\261'!\\@\375G\251GDs#c\334\372\366\317\357EKvD\376C\035N\017^\242R\356\223\320miu\352\203\345\343\373.\r\356\323\353\323\356\207", <incomplete sequence \331>...
(gdb) p b2
$7 = (u8 *) 0x631000028800 ""
(gdb) p state->sais_array
$8 = (s32 *) 0x7ffffab11800
(gdb) p (void) memset(state->sais_array, 0, 292352)
$9 = void
(gdb) c
Continuing.
=================================================================
==1275==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7ffffab5941c at pc 0x000008155a7b bp 0x7ffffffed6a0 sp 0x7ffffffed690

@kspalaiologos from your logs it appears that array is not cleared properly. if n is the size of the input string that following constrain need to be satisfied 1). 1<=primary_index <=n 2). 'A' array need to be of n + 1 elements and cleared.

In your case size_src is 73821, but you only cleared 292352 bytes as oppose to 4 * (73821 + 1) = 295288 bytes.

right; 646212a changes BWT_BOUND so that enough is cleared. seems to pass ASAN now.