mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-27 03:19:35 +03:00
Fix LZ4_uncompress_unknownOutputSize caused panic
Sync with kernel patches for lz4 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/log/lib/lz4 4a3a99 lz4: add overrun checks to lz4_uncompress_unknownoutputsize() d5e7ca LZ4 : fix the data abort issue bea2b5 lib/lz4: Pull out constant tables 99b7e9 lz4: fix system halt at boot kernel on x86_64 Reviewed-by: Chunwei Chen <david.chen@osnexus.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Feng Sun <loyou85@gmail.com> Closes #5975 Closes #5973
This commit is contained in:
parent
bec1067d54
commit
f871ab6ea2
@ -873,6 +873,11 @@ real_LZ4_compress(const char *source, char *dest, int isize, int osize)
|
|||||||
* its code is not present here.
|
* its code is not present here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static const int dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};
|
||||||
|
#if LZ4_ARCH64
|
||||||
|
static const int dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};
|
||||||
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize,
|
LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize,
|
||||||
int maxOutputSize)
|
int maxOutputSize)
|
||||||
@ -886,11 +891,6 @@ LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize,
|
|||||||
BYTE *const oend = op + maxOutputSize;
|
BYTE *const oend = op + maxOutputSize;
|
||||||
BYTE *cpy;
|
BYTE *cpy;
|
||||||
|
|
||||||
size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};
|
|
||||||
#if LZ4_ARCH64
|
|
||||||
size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Main Loop */
|
/* Main Loop */
|
||||||
while (ip < iend) {
|
while (ip < iend) {
|
||||||
unsigned token;
|
unsigned token;
|
||||||
@ -902,6 +902,8 @@ LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize,
|
|||||||
int s = 255;
|
int s = 255;
|
||||||
while ((ip < iend) && (s == 255)) {
|
while ((ip < iend) && (s == 255)) {
|
||||||
s = *ip++;
|
s = *ip++;
|
||||||
|
if (unlikely(length > (size_t)(length + s)))
|
||||||
|
goto _output_error;
|
||||||
length += s;
|
length += s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -944,6 +946,8 @@ LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize,
|
|||||||
if ((length = (token & ML_MASK)) == ML_MASK) {
|
if ((length = (token & ML_MASK)) == ML_MASK) {
|
||||||
while (ip < iend) {
|
while (ip < iend) {
|
||||||
int s = *ip++;
|
int s = *ip++;
|
||||||
|
if (unlikely(length > (size_t)(length + s)))
|
||||||
|
goto _output_error;
|
||||||
length += s;
|
length += s;
|
||||||
if (s == 255)
|
if (s == 255)
|
||||||
continue;
|
continue;
|
||||||
@ -953,7 +957,7 @@ LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize,
|
|||||||
/* copy repeated sequence */
|
/* copy repeated sequence */
|
||||||
if (unlikely(op - ref < STEPSIZE)) {
|
if (unlikely(op - ref < STEPSIZE)) {
|
||||||
#if LZ4_ARCH64
|
#if LZ4_ARCH64
|
||||||
size_t dec64 = dec64table[op-ref];
|
int dec64 = dec64table[op - ref];
|
||||||
#else
|
#else
|
||||||
const int dec64 = 0;
|
const int dec64 = 0;
|
||||||
#endif
|
#endif
|
||||||
@ -978,6 +982,13 @@ LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize,
|
|||||||
* destination buffer
|
* destination buffer
|
||||||
*/
|
*/
|
||||||
goto _output_error;
|
goto _output_error;
|
||||||
|
#if LZ4_ARCH64
|
||||||
|
if ((ref + COPYLENGTH) > oend)
|
||||||
|
#else
|
||||||
|
if ((ref + COPYLENGTH) > oend ||
|
||||||
|
(op + COPYLENGTH) > oend)
|
||||||
|
#endif
|
||||||
|
goto _output_error;
|
||||||
LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH));
|
LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH));
|
||||||
while (op < cpy)
|
while (op < cpy)
|
||||||
*op++ = *ref++;
|
*op++ = *ref++;
|
||||||
@ -999,7 +1010,7 @@ LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize,
|
|||||||
|
|
||||||
/* write overflow error detected */
|
/* write overflow error detected */
|
||||||
_output_error:
|
_output_error:
|
||||||
return (int)(-(((char *)ip) - source));
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user