summaryrefslogtreecommitdiffstats
path: root/lib/lz4.c
diff options
context:
space:
mode:
authorYann Collet <cyan@fb.com>2019-04-17 22:01:53 (GMT)
committerYann Collet <cyan@fb.com>2019-04-17 22:01:53 (GMT)
commit25d96f1e4d84b9fca8f754cd91b822fc32758e5c (patch)
tree7c2818389ade8b2eed6b1900e659427c6dbdafc6 /lib/lz4.c
parent1ed69691a1d1226a6d6e7c465eb1e8c2706833cb (diff)
downloadlz4-25d96f1e4d84b9fca8f754cd91b822fc32758e5c.zip
lz4-25d96f1e4d84b9fca8f754cd91b822fc32758e5c.tar.gz
lz4-25d96f1e4d84b9fca8f754cd91b822fc32758e5c.tar.bz2
fix out-of-bound read within LZ4_decompress_fast()
and deprecate LZ4_decompress_fast(), with deprecation warnings enabled by default. Note that, as a consequence of the fix, LZ4_decompress_fast is now __slower__ than LZ4_decompress_safe(). That's because, since it doesn't know the input buffer size, it must progress more cautiously into the input buffer to ensure to out-of-bound read.
Diffstat (limited to 'lib/lz4.c')
-rw-r--r--lib/lz4.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/lz4.c b/lib/lz4.c
index bd8fa11..2f8aa04 100644
--- a/lib/lz4.c
+++ b/lib/lz4.c
@@ -135,6 +135,9 @@
# endif /* _MSC_VER */
#endif /* LZ4_FORCE_INLINE */
+#undef LZ4_FORCE_INLINE
+#define LZ4_FORCE_INLINE static /* disable */
+
/* LZ4_FORCE_O2_GCC_PPC64LE and LZ4_FORCE_O2_INLINE_GCC_PPC64LE
* Gcc on ppc64le generates an unrolled SIMDized loop for LZ4_wildCopy,
* together with a simple 8-byte copy loop as a fall-back path.
@@ -1671,7 +1674,10 @@ LZ4_decompress_generic(
{
goto safe_literal_copy;
}
- LZ4_wildCopy32(op, ip, cpy);
+ if (endOnInput)
+ LZ4_wildCopy32(op, ip, cpy);
+ else
+ LZ4_wildCopy(op, ip, cpy); /* LZ4_decompress_fast() cannot copy more than 8 bytes at a time : it doesn't know input length, and only relies on end-of-block properties */
ip += length; op = cpy;
} else {
cpy = op+length;
@@ -1681,7 +1687,12 @@ LZ4_decompress_generic(
goto safe_literal_copy;
}
/* Literals can only be 14, but hope compilers optimize if we copy by a register size */
- memcpy(op, ip, 16);
+ if (endOnInput)
+ memcpy(op, ip, 16);
+ else { /* LZ4_decompress_fast() cannot copy more than 8 bytes at a time : it doesn't know input length, and only relies on end-of-block properties */
+ memcpy(op, ip, 8);
+ if (length > 8) memcpy(op+8, ip+8, 8);
+ }
ip += length; op = cpy;
}