9
0
Fork 0

Revert "lzo: properly check for overruns"

This reverts barebox commit ecb1dc0b1e
This corresponds to kernel commit af958a38a60c7ca3d8

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>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stefan Müller-Klieser <s.mueller-klieser@phytec.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Stefan Müller-Klieser 2015-03-24 11:03:52 +01:00 committed by Sascha Hauer
parent 865d5a14f9
commit 69a6dcdc0e
1 changed files with 22 additions and 42 deletions

View File

@ -16,34 +16,14 @@
#include <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)
unsigned char *out, size_t *out_len)
{
unsigned char *op;
const unsigned char *ip;
@ -75,14 +55,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 {
@ -98,8 +78,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);
@ -112,7 +92,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;
@ -136,10 +116,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);
@ -154,10 +134,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;
@ -171,7 +151,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;
@ -181,7 +161,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;
@ -189,7 +169,7 @@ copy_literal_run:
continue;
}
} else {
NEED_OP(t, 0);
NEED_OP(t);
do {
*op++ = *m_pos++;
} while (op < oe);
@ -198,7 +178,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;
@ -211,15 +191,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--;