summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorYann Collet <Cyan4973@users.noreply.github.com>2019-04-18 21:29:20 (GMT)
committerGitHub <noreply@github.com>2019-04-18 21:29:20 (GMT)
commit5a6d72447ae998b387794df1135023689aa89995 (patch)
tree2297bceac7efea6c8c1a9b29457a25f32dc5c608 /lib
parentb59fd652e80f3dc494ed80cc2521f7777c85a0dd (diff)
parent4f6de46f60fc7b158e7fc5ce24eb06c39d8b6ce2 (diff)
downloadlz4-5a6d72447ae998b387794df1135023689aa89995.zip
lz4-5a6d72447ae998b387794df1135023689aa89995.tar.gz
lz4-5a6d72447ae998b387794df1135023689aa89995.tar.bz2
Merge pull request #678 from lz4/decFast
Fix out-of-bound read in LZ4_decompress_fast()
Diffstat (limited to 'lib')
-rw-r--r--lib/lz4.c12
-rw-r--r--lib/lz4.h19
2 files changed, 20 insertions, 11 deletions
diff --git a/lib/lz4.c b/lib/lz4.c
index bd8fa11..c38932e 100644
--- a/lib/lz4.c
+++ b/lib/lz4.c
@@ -1671,7 +1671,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 +1684,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;
}
diff --git a/lib/lz4.h b/lib/lz4.h
index 1589be9..962f5e6 100644
--- a/lib/lz4.h
+++ b/lib/lz4.h
@@ -631,14 +631,15 @@ LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") LZ4LIB_API int LZ4
LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize);
/*! LZ4_decompress_fast() : **unsafe!**
- * These functions are generally slightly faster than LZ4_decompress_safe(),
- * though the difference is small (generally ~5%).
- * However, the real cost is a risk : LZ4_decompress_safe() is protected vs malformed input, while `LZ4_decompress_fast()` is not, making it a security liability.
+ * These functions used to be faster than LZ4_decompress_safe(),
+ * but it has changed, and they are now slower than LZ4_decompress_safe().
+ * This is because LZ4_decompress_fast() doesn't know the input size,
+ * and therefore must progress more cautiously in the input buffer to not read beyond the end of block.
+ * On top of that `LZ4_decompress_fast()` is not protected vs malformed or malicious inputs, making it a security liability.
* As a consequence, LZ4_decompress_fast() is strongly discouraged, and deprecated.
- * These functions will generate a deprecation warning in the future.
*
- * Last LZ4_decompress_fast() specificity is that it can decompress a block without knowing its compressed size.
- * Note that even that functionality could be achieved in a more secure manner if need be,
+ * Only LZ4_decompress_fast() specificity is that it can decompress a block without knowing its compressed size.
+ * Even that functionality could be achieved in a more secure manner if need be,
* though it would require new prototypes, and adaptation of the implementation to this new use case.
*
* Parameters:
@@ -655,11 +656,11 @@ LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4
* As a consequence, use these functions in trusted environments with trusted data **only**.
*/
-/* LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe() instead") */
+LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe() instead")
LZ4LIB_API int LZ4_decompress_fast (const char* src, char* dst, int originalSize);
-/* LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_continue() instead") */
+LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_continue() instead")
LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int originalSize);
-/* LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_usingDict() instead") */
+LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_usingDict() instead")
LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int originalSize, const char* dictStart, int dictSize);
/*! LZ4_resetStream() :