diff options
author | Nick Terrell <terrelln@fb.com> | 2018-04-23 20:14:19 (GMT) |
---|---|---|
committer | Nick Terrell <terrelln@fb.com> | 2018-04-23 20:34:18 (GMT) |
commit | bb83cad98fdb15a7ade4cde582b98e836fb8ef11 (patch) | |
tree | 17bd7c7197b46ca8b8f1dfcc8cd501ec9e36d3bd /tests/fuzzer.c | |
parent | 996d211aca5407c97b0c3736f20ae599f05f0d44 (diff) | |
download | lz4-bb83cad98fdb15a7ade4cde582b98e836fb8ef11.zip lz4-bb83cad98fdb15a7ade4cde582b98e836fb8ef11.tar.gz lz4-bb83cad98fdb15a7ade4cde582b98e836fb8ef11.tar.bz2 |
Fix input size validation edge cases
The bug is a read up to 2 bytes past the end of the buffer.
There are three cases for this bug, one for each test case added.
* An empty input causes `token = *ip++` to read one byte too far.
* A one byte input with `(token >> ML_BITS) == RUN_MASK` causes
one extra byte to be read without validation. This could be
combined with the first bug to cause 2 extra bytes to be read.
* The case pointed out in issue #508, where `ip == iend` at the
beginning of the loop after taking the shortcut.
Benchmarks show no regressions on clang or gcc-7 on both my mac
and devserver.
Fixes #508.
Diffstat (limited to 'tests/fuzzer.c')
-rw-r--r-- | tests/fuzzer.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 244cc4f..def5230 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -487,6 +487,32 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c ret = LZ4_decompress_fast(compressedBuffer, decodedBuffer, blockSize+1); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_fast should have failed, due to Output Size being too large"); + /* Test decoding with empty input */ + FUZ_DISPLAYTEST("LZ4_decompress_safe() with empty input"); + LZ4_decompress_safe(NULL, decodedBuffer, 0, blockSize); + + /* Test decoding with a one byte input */ + FUZ_DISPLAYTEST("LZ4_decompress_safe() with one byte input"); + { char const tmp = 0xFF; + LZ4_decompress_safe(&tmp, decodedBuffer, 1, blockSize); + } + + /* Test decoding shortcut edge case */ + FUZ_DISPLAYTEST("LZ4_decompress_safe() with shortcut edge case"); + { char tmp[17]; + unsigned long i; + /* 14 bytes of literals, followed by a 14 byte match. + * Should not read beyond the end of the buffer. + * See https://github.com/lz4/lz4/issues/508. */ + *tmp = 0xEE; + memset(tmp + 1, 0, 14); + tmp[15] = 14; + tmp[16] = 0; + ret = LZ4_decompress_safe(tmp, decodedBuffer, sizeof(tmp), blockSize); + FUZ_CHECKTEST(ret >= 0, "LZ4_decompress_safe() should fail"); + } + + /* Test decoding with output size exactly what's necessary => must work */ FUZ_DISPLAYTEST(); decodedBuffer[blockSize] = 0; |