Closed
Description
Sorry to bug you again, I'm sure this is getting old…
I'm adding a new test to Squash, and xpress-huffman falls victim. I've ported the test to ms-compress' API:
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "include/mscomp.h"
#include "include/xpress_huff.h"
#define CODEC MSCOMP_XPRESS_HUFF
#define LOREM_IPSUM (uint8_t*) \
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vulputate " \
"lectus nisl, vitae ultricies justo dictum nec. Vestibulum ante ipsum " \
"primis in faucibus orci luctus et ultrices posuere cubilia Curae; " \
"Suspendisse suscipit quam a lectus adipiscing, sed tempor purus " \
"cursus. Vivamus id nulla eget elit eleifend molestie. Integer " \
"sollicitudin lorem enim, eu eleifend orci facilisis sed. Pellentesque " \
"sodales luctus enim vel viverra. Cras interdum vel nisl in " \
"facilisis. Curabitur sollicitudin tortor vel congue " \
"auctor. Suspendisse egestas orci vitae neque placerat blandit.\n" \
"\n" \
"Aenean sed nisl ultricies, vulputate lorem a, suscipit nulla. Donec " \
"egestas volutpat neque a eleifend. Nullam porta semper " \
"nunc. Pellentesque adipiscing molestie magna, quis pulvinar metus " \
"gravida sit amet. Vestibulum mollis et sapien eu posuere. Quisque " \
"tristique dignissim ante et aliquet. Phasellus vulputate condimentum " \
"nulla in vulputate.\n" \
"\n" \
"Nullam volutpat tellus at nisi auctor, vitae mattis nibh viverra. Nunc " \
"vitae lectus tristique, ultrices nibh quis, lobortis elit. Curabitur " \
"at vestibulum nisi, nec facilisis ante. Nulla pharetra blandit lacus, " \
"at sodales nulla placerat eget. Nulla congue varius tortor, sit amet " \
"tempor est mattis nec. Praesent vitae tristique ipsum, rhoncus " \
"tristique lorem. Sed et erat tristique ligula accumsan fringilla eu in " \
"urna. Donec dapibus hendrerit neque nec venenatis. In euismod sapien " \
"ipsum, auctor consectetur mi dapibus hendrerit.\n" \
"\n" \
"Phasellus sagittis rutrum velit, in sodales nibh imperdiet a. Integer " \
"vitae arcu blandit nibh laoreet scelerisque eu sit amet eros. Aenean " \
"odio felis, aliquam in eros at, ornare luctus magna. In semper " \
"tincidunt nunc, sollicitudin gravida nunc laoreet eu. Cras eu tempor " \
"sapien, ut dignissim elit. Proin eleifend arcu tempus, semper erat et, " \
"accumsan erat. Praesent vulputate diam mi, eget mollis leo " \
"pellentesque eget. Aliquam eu tortor posuere, posuere velit sed, " \
"suscipit eros. Nam eu leo vitae mauris condimentum lobortis non quis " \
"mauris. Nulla venenatis fringilla urna nec venenatis. Nam eget velit " \
"nulla. Proin ut malesuada felis. Suspendisse vitae nunc neque. Donec " \
"faucibus tempor lacinia. Vivamus ac vulputate sapien, eget lacinia " \
"nisl.\n" \
"\n" \
"Curabitur eu dolor molestie, ullamcorper lorem quis, egestas " \
"urna. Suspendisse in arcu sed justo blandit condimentum. Ut auctor, " \
"sem quis condimentum mattis, est purus pulvinar elit, quis viverra " \
"nibh metus ac diam. Etiam aliquet est eu dui fermentum consequat. Cras " \
"auctor diam eget bibendum sagittis. Aenean elementum purus sit amet " \
"sem euismod, non varius felis dictum. Aliquam tempus pharetra ante a " \
"sagittis. Curabitur ut urna felis. Etiam sed vulputate nisi. Praesent " \
"at libero eleifend, sagittis quam a, varius sapien."
#define LOREM_IPSUM_LENGTH ((size_t) 2725)
int main(int argc, char *argv[]) {
size_t compressed_size = ms_max_compressed_size(CODEC, LOREM_IPSUM_LENGTH);
uint8_t* compressed = (uint8_t*) malloc(compressed_size);
uint8_t decompressed[LOREM_IPSUM_LENGTH];
size_t decompressed_size;
assert(compressed_size <= sizeof(compressed));
MSCompStatus status =
ms_compress (CODEC,
LOREM_IPSUM, LOREM_IPSUM_LENGTH,
compressed, &compressed_size);
/* Now try to decompress progressively smaller slices of the
compressed buffer. */
while (--compressed_size > 0) {
decompressed_size = sizeof(decompressed);
compressed = (uint8_t*) realloc(compressed, compressed_size);
ms_decompress(CODEC, compressed, compressed_size, decompressed, &decompressed_size);
}
assert (status == MSCOMP_OK);
free (compressed);
printf("Works\n");
return 0;
}
Run with AddressSanitizer:
nemequ@peltast:~/local/src/ms-compress$ git:(master) 4A g++ -g -DNDEBUG -O2 -fno-omit-frame-pointer -fsanitize=address -o truncated truncated.c src/*.cpp && ./truncated
=================================================================
==15889==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61b00001e905 at pc 0x000000414691 bp 0x7fff59c2aec0 sp 0x7fff59c2aeb0
READ of size 2 at 0x61b00001e905 thread T0
#0 0x414690 in InputBitstream::Skip_Fast(unsigned char) src/../include/mscomp/Bitstream.h:84
#1 0x414690 in InputBitstream::ReadBits_Fast(unsigned char) src/../include/mscomp/Bitstream.h:99
#2 0x414690 in xpress_huff_decompress_chunk src/xpress_huff_decompress.cpp:111
#3 0x414690 in xpress_huff_decompress src/xpress_huff_decompress.cpp:157
#4 0x400fe6 in main /home/nemequ/local/src/ms-compress/truncated.c:79
#5 0x7f6639629730 in __libc_start_main (/lib64/libc.so.6+0x20730)
#6 0x401198 in _start (/home/nemequ/local/src/ms-compress/truncated+0x401198)
0x61b00001e906 is located 0 bytes to the right of 1414-byte region [0x61b00001e380,0x61b00001e906)
allocated by thread T0 here:
#0 0x7f663a33b150 in realloc (/lib64/libasan.so.3+0xc7150)
#1 0x400fc5 in main /home/nemequ/local/src/ms-compress/truncated.c:78
#2 0x7f6639629730 in __libc_start_main (/lib64/libc.so.6+0x20730)
SUMMARY: AddressSanitizer: heap-buffer-overflow src/../include/mscomp/Bitstream.h:84 in InputBitstream::Skip_Fast(unsigned char)
Shadow bytes around the buggy address:
0x0c367fffbcd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c367fffbce0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c367fffbcf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c367fffbd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c367fffbd10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c367fffbd20:[06]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c367fffbd30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c367fffbd40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c367fffbd50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c367fffbd60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c367fffbd70: 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
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
Left alloca redzone: ca
Right alloca redzone: cb
==15889==ABORTING
FWIW, you're in good company. 6 codecs fell to this issue.
Note that compiling without NDEBUG defined does cause an assertion failure.