lz4: check for underruns
authorJan Beulich <jbeulich@suse.com>
Mon, 4 Aug 2014 11:43:03 +0000 (13:43 +0200)
committerJan Beulich <jbeulich@suse.com>
Mon, 4 Aug 2014 11:43:03 +0000 (13:43 +0200)
While overruns are already being taken care of, underruns (resulting
from overflows in the respective "op + length" (or similar) operations
weren't.

This is CVE-2014-4611.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
xen/common/lz4/decompress.c

index 40b33814b650581473d8591492d5f739e9b370e5..5cf8f37711c28335fde10e335219eb5f0523b558 100644 (file)
@@ -84,6 +84,8 @@ static int INIT lz4_uncompress(const unsigned char *source, unsigned char *dest,
                        ip += length;
                        break; /* EOF */
                }
+               if (unlikely((unsigned long)cpy < (unsigned long)op))
+                       goto _output_error;
                LZ4_WILDCOPY(ip, op, cpy);
                ip -= (op - cpy);
                op = cpy;
@@ -142,6 +144,8 @@ static int INIT lz4_uncompress(const unsigned char *source, unsigned char *dest,
                                goto _output_error;
                        continue;
                }
+               if (unlikely((unsigned long)cpy < (unsigned long)op))
+                       goto _output_error;
                LZ4_SECURECOPY(ref, op, cpy);
                op = cpy; /* correction */
        }
@@ -207,6 +211,8 @@ static int lz4_uncompress_unknownoutputsize(const unsigned char *source,
                        op += length;
                        break;/* Necessarily EOF, due to parsing restrictions */
                }
+               if (unlikely((unsigned long)cpy < (unsigned long)op))
+                       goto _output_error;
                LZ4_WILDCOPY(ip, op, cpy);
                ip -= (op - cpy);
                op = cpy;
@@ -270,6 +276,8 @@ static int lz4_uncompress_unknownoutputsize(const unsigned char *source,
                                goto _output_error;
                        continue;
                }
+               if (unlikely((unsigned long)cpy < (unsigned long)op))
+                       goto _output_error;
                LZ4_SECURECOPY(ref, op, cpy);
                op = cpy; /* correction */
        }