Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af958a38 authored by Willy Tarreau's avatar Willy Tarreau Committed by Greg Kroah-Hartman
Browse files

Revert "lzo: properly check for overruns"



This reverts commit 206a81c1 ("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: default avatarWillem Pinckaers <willem@lekkertech.net>
Cc: "Don A. Bailey" <donb@securitymouse.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d98a0526
Loading
Loading
Loading
Loading
+21 −41
Original line number Diff line number Diff line
@@ -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 char *in, size_t in_len,
					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--;