Closed nemequ closed 8 years ago
If you attempt to compress a single byte with xpress-huffman it will read outside the buffer you provide to it. Test case:
#include <stdio.h> #include <assert.h> #include <stdint.h> #include <stdlib.h> #define CODEC MSCOMP_XPRESS_HUFF #include "include/mscomp.h" int main(int argc, char *argv[]) { uint8_t uncompressed; uint8_t compressed[1024]; uint8_t decompressed; size_t compressed_length = sizeof(compressed); size_t decompressed_length = 1; assert (ms_max_compressed_size (CODEC, 1) <= sizeof(compressed)); compressed_length = ms_max_compressed_size (CODEC, 1); uncompressed = (uint8_t) 42; /* <- doesn't matter */ MSCompStatus status = ms_compress (CODEC, &uncompressed, 1, compressed, &compressed_length); assert (status == MSCOMP_OK); status = ms_decompress(CODEC, compressed, compressed_length, &decompressed, &decompressed_length); assert (status == MSCOMP_OK); assert (decompressed == uncompressed); return 0; }
Sample output from AddressSanitizer:
================================================================= ==17331==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc497e8101 at pc 0x00000041497a bp 0x7ffc496a6fe0 sp 0x7ffc496a6fd0 READ of size 1 at 0x7ffc497e8101 thread T0 #0 0x414979 in XpressDictionary<65535u, 65536u, 15u, 3u>::Fill(unsigned char const*) src/../include/mscomp/XpressDictionary.h:103 #1 0x412434 in xh_compress_lz77 src/xpress_huff_compress.cpp:60 #2 0x4141d5 in xpress_huff_compress src/xpress_huff_compress.cpp:297 #3 0x408daf in ms_compress src/mscomp.cpp:116 #4 0x401281 in main /home/nemequ/local/src/ms-compress/compress.c:22 #5 0x7f12e5bae6ff in __libc_start_main (/lib64/libc.so.6+0x206ff) #6 0x401048 in _start (/home/nemequ/local/src/ms-compress/compress+0x401048) Address 0x7ffc497e8101 is located in stack of thread T0 at offset 33 in frame #0 0x401125 in main /home/nemequ/local/src/ms-compress/compress.c:10 This frame has 5 object(s): [32, 33) 'uncompressed' <== Memory access at offset 33 overflows this variable [96, 97) 'decompressed' [160, 168) 'compressed_length' [224, 232) 'decompressed_length' [288, 1312) 'compressed' HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-overflow src/../include/mscomp/XpressDictionary.h:103 XpressDictionary<65535u, 65536u, 15u, 3u>::Fill(unsigned char const*) Shadow bytes around the buggy address: 0x1000092f4fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000092f4fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000092f4ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000092f5000: 00 00 00 00 00 00 00 00 f3 f3 f3 f3 00 00 00 00 0x1000092f5010: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 =>0x1000092f5020:[01]f4 f4 f4 f2 f2 f2 f2 01 f4 f4 f4 f2 f2 f2 f2 0x1000092f5030: 00 f4 f4 f4 f2 f2 f2 f2 00 f4 f4 f4 f2 f2 f2 f2 0x1000092f5040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000092f5050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000092f5060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000092f5070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 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 Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 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 ==17331==ABORTING
If you attempt to compress a single byte with xpress-huffman it will read outside the buffer you provide to it. Test case:
Sample output from AddressSanitizer: