summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
d98a052)
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>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
#include <linux/lzo.h>
#include "lzodefs.h"
#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)
int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
unsigned char *out, size_t *out_len)
while (unlikely(*ip == 0)) {
t += 255;
ip++;
while (unlikely(*ip == 0)) {
t += 255;
ip++;
}
t += 15 + *ip++;
}
t += 3;
copy_literal_run:
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
}
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 {
const unsigned char *ie = ip + t;
unsigned char *oe = op + t;
do {
- NEED_OP(t, 0);
- NEED_IP(t, 3);
+ NEED_OP(t);
+ NEED_IP(t + 3);
do {
*op++ = *ip++;
} while (--t > 0);
do {
*op++ = *ip++;
} while (--t > 0);
m_pos -= t >> 2;
m_pos -= *ip++ << 2;
TEST_LB(m_pos);
m_pos -= t >> 2;
m_pos -= *ip++ << 2;
TEST_LB(m_pos);
op[0] = m_pos[0];
op[1] = m_pos[1];
op += 2;
op[0] = m_pos[0];
op[1] = m_pos[1];
op += 2;
while (unlikely(*ip == 0)) {
t += 255;
ip++;
while (unlikely(*ip == 0)) {
t += 255;
ip++;
}
m_pos = op - 1;
next = get_unaligned_le16(ip);
}
m_pos = op - 1;
next = get_unaligned_le16(ip);
while (unlikely(*ip == 0)) {
t += 255;
ip++;
while (unlikely(*ip == 0)) {
t += 255;
ip++;
}
next = get_unaligned_le16(ip);
ip += 2;
}
next = get_unaligned_le16(ip);
ip += 2;
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
if (op - m_pos >= 8) {
unsigned char *oe = op + t;
#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;
do {
COPY8(op, m_pos);
op += 8;
m_pos += 8;
} while (op < oe);
op = oe;
m_pos += 8;
} while (op < oe);
op = oe;
state = next;
COPY4(op, ip);
op += next;
state = next;
COPY4(op, ip);
op += next;
do {
*op++ = *m_pos++;
} while (op < oe);
do {
*op++ = *m_pos++;
} while (op < oe);
#endif
{
unsigned char *oe = op + t;
#endif
{
unsigned char *oe = op + t;
op[0] = m_pos[0];
op[1] = m_pos[1];
op += 2;
op[0] = m_pos[0];
op[1] = m_pos[1];
op += 2;
state = next;
t = next;
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
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
{
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--;
while (t > 0) {
*op++ = *ip++;
t--;