| From af958a38a60c7ca3d8a39c918c1baa2ff7b6b233 Mon Sep 17 00:00:00 2001 |
| From: Willy Tarreau <w@1wt.eu> |
| Date: Sat, 27 Sep 2014 12:31:36 +0200 |
| Subject: Revert "lzo: properly check for overruns" |
| |
| From: Willy Tarreau <w@1wt.eu> |
| |
| commit af958a38a60c7ca3d8a39c918c1baa2ff7b6b233 upstream. |
| |
| This reverts commit 206a81c ("lzo: properly check for overruns"). |
| |
| As analysed by Willem Pinckaers, this fix is still incomplete on |
| certain rare corner cases, and it is easier to restart from the |
| original code. |
| |
| Reported-by: Willem Pinckaers <willem@lekkertech.net> |
| Cc: "Don A. Bailey" <donb@securitymouse.com> |
| Signed-off-by: Willy Tarreau <w@1wt.eu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| lib/lzo/lzo1x_decompress_safe.c | 62 +++++++++++++--------------------------- |
| 1 file changed, 21 insertions(+), 41 deletions(-) |
| |
| --- a/lib/lzo/lzo1x_decompress_safe.c |
| +++ b/lib/lzo/lzo1x_decompress_safe.c |
| @@ -19,31 +19,11 @@ |
| #include <linux/lzo.h> |
| #include "lzodefs.h" |
| |
| -#define HAVE_IP(t, x) \ |
| - (((size_t)(ip_end - ip) >= (size_t)(t + x)) && \ |
| - (((t + x) >= t) && ((t + x) >= x))) |
| - |
| -#define HAVE_OP(t, x) \ |
| - (((size_t)(op_end - op) >= (size_t)(t + x)) && \ |
| - (((t + x) >= t) && ((t + x) >= x))) |
| - |
| -#define NEED_IP(t, x) \ |
| - do { \ |
| - if (!HAVE_IP(t, x)) \ |
| - goto input_overrun; \ |
| - } while (0) |
| - |
| -#define NEED_OP(t, x) \ |
| - do { \ |
| - if (!HAVE_OP(t, x)) \ |
| - goto output_overrun; \ |
| - } while (0) |
| - |
| -#define TEST_LB(m_pos) \ |
| - do { \ |
| - if ((m_pos) < out) \ |
| - goto lookbehind_overrun; \ |
| - } while (0) |
| +#define HAVE_IP(x) ((size_t)(ip_end - ip) >= (size_t)(x)) |
| +#define HAVE_OP(x) ((size_t)(op_end - op) >= (size_t)(x)) |
| +#define NEED_IP(x) if (!HAVE_IP(x)) goto input_overrun |
| +#define NEED_OP(x) if (!HAVE_OP(x)) goto output_overrun |
| +#define TEST_LB(m_pos) if ((m_pos) < out) goto lookbehind_overrun |
| |
| int lzo1x_decompress_safe(const unsigned char *in, size_t in_len, |
| unsigned char *out, size_t *out_len) |
| @@ -78,14 +58,14 @@ int lzo1x_decompress_safe(const unsigned |
| while (unlikely(*ip == 0)) { |
| t += 255; |
| ip++; |
| - NEED_IP(1, 0); |
| + NEED_IP(1); |
| } |
| t += 15 + *ip++; |
| } |
| t += 3; |
| copy_literal_run: |
| #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) |
| - if (likely(HAVE_IP(t, 15) && HAVE_OP(t, 15))) { |
| + if (likely(HAVE_IP(t + 15) && HAVE_OP(t + 15))) { |
| const unsigned char *ie = ip + t; |
| unsigned char *oe = op + t; |
| do { |
| @@ -101,8 +81,8 @@ copy_literal_run: |
| } else |
| #endif |
| { |
| - NEED_OP(t, 0); |
| - NEED_IP(t, 3); |
| + NEED_OP(t); |
| + NEED_IP(t + 3); |
| do { |
| *op++ = *ip++; |
| } while (--t > 0); |
| @@ -115,7 +95,7 @@ copy_literal_run: |
| m_pos -= t >> 2; |
| m_pos -= *ip++ << 2; |
| TEST_LB(m_pos); |
| - NEED_OP(2, 0); |
| + NEED_OP(2); |
| op[0] = m_pos[0]; |
| op[1] = m_pos[1]; |
| op += 2; |
| @@ -139,10 +119,10 @@ copy_literal_run: |
| while (unlikely(*ip == 0)) { |
| t += 255; |
| ip++; |
| - NEED_IP(1, 0); |
| + NEED_IP(1); |
| } |
| t += 31 + *ip++; |
| - NEED_IP(2, 0); |
| + NEED_IP(2); |
| } |
| m_pos = op - 1; |
| next = get_unaligned_le16(ip); |
| @@ -157,10 +137,10 @@ copy_literal_run: |
| while (unlikely(*ip == 0)) { |
| t += 255; |
| ip++; |
| - NEED_IP(1, 0); |
| + NEED_IP(1); |
| } |
| t += 7 + *ip++; |
| - NEED_IP(2, 0); |
| + NEED_IP(2); |
| } |
| next = get_unaligned_le16(ip); |
| ip += 2; |
| @@ -174,7 +154,7 @@ copy_literal_run: |
| #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) |
| if (op - m_pos >= 8) { |
| unsigned char *oe = op + t; |
| - if (likely(HAVE_OP(t, 15))) { |
| + if (likely(HAVE_OP(t + 15))) { |
| do { |
| COPY8(op, m_pos); |
| op += 8; |
| @@ -184,7 +164,7 @@ copy_literal_run: |
| m_pos += 8; |
| } while (op < oe); |
| op = oe; |
| - if (HAVE_IP(6, 0)) { |
| + if (HAVE_IP(6)) { |
| state = next; |
| COPY4(op, ip); |
| op += next; |
| @@ -192,7 +172,7 @@ copy_literal_run: |
| continue; |
| } |
| } else { |
| - NEED_OP(t, 0); |
| + NEED_OP(t); |
| do { |
| *op++ = *m_pos++; |
| } while (op < oe); |
| @@ -201,7 +181,7 @@ copy_literal_run: |
| #endif |
| { |
| unsigned char *oe = op + t; |
| - NEED_OP(t, 0); |
| + NEED_OP(t); |
| op[0] = m_pos[0]; |
| op[1] = m_pos[1]; |
| op += 2; |
| @@ -214,15 +194,15 @@ match_next: |
| state = next; |
| t = next; |
| #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) |
| - if (likely(HAVE_IP(6, 0) && HAVE_OP(4, 0))) { |
| + if (likely(HAVE_IP(6) && HAVE_OP(4))) { |
| COPY4(op, ip); |
| op += t; |
| ip += t; |
| } else |
| #endif |
| { |
| - NEED_IP(t, 3); |
| - NEED_OP(t, 0); |
| + NEED_IP(t + 3); |
| + NEED_OP(t); |
| while (t > 0) { |
| *op++ = *ip++; |
| t--; |