aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilly Tarreau <w@1wt.eu>2014-09-27 06:31:36 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-09-28 05:08:01 -0400
commitaf958a38a60c7ca3d8a39c918c1baa2ff7b6b233 (patch)
tree933dcf1f3e11ad913d5408c7cbcaa2925d78a587
parentd98a0526434d27e261f622cf9d2e0028b5ff1a00 (diff)
Revert "lzo: properly check for overruns"
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>
-rw-r--r--lib/lzo/lzo1x_decompress_safe.c62
1 files changed, 21 insertions, 41 deletions
diff --git a/lib/lzo/lzo1x_decompress_safe.c b/lib/lzo/lzo1x_decompress_safe.c
index 8563081e8da3..569985d522d5 100644
--- a/lib/lzo/lzo1x_decompress_safe.c
+++ b/lib/lzo/lzo1x_decompress_safe.c
@@ -19,31 +19,11 @@
19#include <linux/lzo.h> 19#include <linux/lzo.h>
20#include "lzodefs.h" 20#include "lzodefs.h"
21 21
22#define HAVE_IP(t, x) \ 22#define HAVE_IP(x) ((size_t)(ip_end - ip) >= (size_t)(x))
23 (((size_t)(ip_end - ip) >= (size_t)(t + x)) && \ 23#define HAVE_OP(x) ((size_t)(op_end - op) >= (size_t)(x))
24 (((t + x) >= t) && ((t + x) >= x))) 24#define NEED_IP(x) if (!HAVE_IP(x)) goto input_overrun
25 25#define NEED_OP(x) if (!HAVE_OP(x)) goto output_overrun
26#define HAVE_OP(t, x) \ 26#define TEST_LB(m_pos) if ((m_pos) < out) goto lookbehind_overrun
27 (((size_t)(op_end - op) >= (size_t)(t + x)) && \
28 (((t + x) >= t) && ((t + x) >= x)))
29
30#define NEED_IP(t, x) \
31 do { \
32 if (!HAVE_IP(t, x)) \
33 goto input_overrun; \
34 } while (0)
35
36#define NEED_OP(t, x) \
37 do { \
38 if (!HAVE_OP(t, x)) \
39 goto output_overrun; \
40 } while (0)
41
42#define TEST_LB(m_pos) \
43 do { \
44 if ((m_pos) < out) \
45 goto lookbehind_overrun; \
46 } while (0)
47 27
48int lzo1x_decompress_safe(const unsigned char *in, size_t in_len, 28int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
49 unsigned char *out, size_t *out_len) 29 unsigned char *out, size_t *out_len)
@@ -78,14 +58,14 @@ int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
78 while (unlikely(*ip == 0)) { 58 while (unlikely(*ip == 0)) {
79 t += 255; 59 t += 255;
80 ip++; 60 ip++;
81 NEED_IP(1, 0); 61 NEED_IP(1);
82 } 62 }
83 t += 15 + *ip++; 63 t += 15 + *ip++;
84 } 64 }
85 t += 3; 65 t += 3;
86copy_literal_run: 66copy_literal_run:
87#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) 67#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
88 if (likely(HAVE_IP(t, 15) && HAVE_OP(t, 15))) { 68 if (likely(HAVE_IP(t + 15) && HAVE_OP(t + 15))) {
89 const unsigned char *ie = ip + t; 69 const unsigned char *ie = ip + t;
90 unsigned char *oe = op + t; 70 unsigned char *oe = op + t;
91 do { 71 do {
@@ -101,8 +81,8 @@ copy_literal_run:
101 } else 81 } else
102#endif 82#endif
103 { 83 {
104 NEED_OP(t, 0); 84 NEED_OP(t);
105 NEED_IP(t, 3); 85 NEED_IP(t + 3);
106 do { 86 do {
107 *op++ = *ip++; 87 *op++ = *ip++;
108 } while (--t > 0); 88 } while (--t > 0);
@@ -115,7 +95,7 @@ copy_literal_run:
115 m_pos -= t >> 2; 95 m_pos -= t >> 2;
116 m_pos -= *ip++ << 2; 96 m_pos -= *ip++ << 2;
117 TEST_LB(m_pos); 97 TEST_LB(m_pos);
118 NEED_OP(2, 0); 98 NEED_OP(2);
119 op[0] = m_pos[0]; 99 op[0] = m_pos[0];
120 op[1] = m_pos[1]; 100 op[1] = m_pos[1];
121 op += 2; 101 op += 2;
@@ -139,10 +119,10 @@ copy_literal_run:
139 while (unlikely(*ip == 0)) { 119 while (unlikely(*ip == 0)) {
140 t += 255; 120 t += 255;
141 ip++; 121 ip++;
142 NEED_IP(1, 0); 122 NEED_IP(1);
143 } 123 }
144 t += 31 + *ip++; 124 t += 31 + *ip++;
145 NEED_IP(2, 0); 125 NEED_IP(2);
146 } 126 }
147 m_pos = op - 1; 127 m_pos = op - 1;
148 next = get_unaligned_le16(ip); 128 next = get_unaligned_le16(ip);
@@ -157,10 +137,10 @@ copy_literal_run:
157 while (unlikely(*ip == 0)) { 137 while (unlikely(*ip == 0)) {
158 t += 255; 138 t += 255;
159 ip++; 139 ip++;
160 NEED_IP(1, 0); 140 NEED_IP(1);
161 } 141 }
162 t += 7 + *ip++; 142 t += 7 + *ip++;
163 NEED_IP(2, 0); 143 NEED_IP(2);
164 } 144 }
165 next = get_unaligned_le16(ip); 145 next = get_unaligned_le16(ip);
166 ip += 2; 146 ip += 2;
@@ -174,7 +154,7 @@ copy_literal_run:
174#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) 154#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
175 if (op - m_pos >= 8) { 155 if (op - m_pos >= 8) {
176 unsigned char *oe = op + t; 156 unsigned char *oe = op + t;
177 if (likely(HAVE_OP(t, 15))) { 157 if (likely(HAVE_OP(t + 15))) {
178 do { 158 do {
179 COPY8(op, m_pos); 159 COPY8(op, m_pos);
180 op += 8; 160 op += 8;
@@ -184,7 +164,7 @@ copy_literal_run:
184 m_pos += 8; 164 m_pos += 8;
185 } while (op < oe); 165 } while (op < oe);
186 op = oe; 166 op = oe;
187 if (HAVE_IP(6, 0)) { 167 if (HAVE_IP(6)) {
188 state = next; 168 state = next;
189 COPY4(op, ip); 169 COPY4(op, ip);
190 op += next; 170 op += next;
@@ -192,7 +172,7 @@ copy_literal_run:
192 continue; 172 continue;
193 } 173 }
194 } else { 174 } else {
195 NEED_OP(t, 0); 175 NEED_OP(t);
196 do { 176 do {
197 *op++ = *m_pos++; 177 *op++ = *m_pos++;
198 } while (op < oe); 178 } while (op < oe);
@@ -201,7 +181,7 @@ copy_literal_run:
201#endif 181#endif
202 { 182 {
203 unsigned char *oe = op + t; 183 unsigned char *oe = op + t;
204 NEED_OP(t, 0); 184 NEED_OP(t);
205 op[0] = m_pos[0]; 185 op[0] = m_pos[0];
206 op[1] = m_pos[1]; 186 op[1] = m_pos[1];
207 op += 2; 187 op += 2;
@@ -214,15 +194,15 @@ match_next:
214 state = next; 194 state = next;
215 t = next; 195 t = next;
216#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) 196#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
217 if (likely(HAVE_IP(6, 0) && HAVE_OP(4, 0))) { 197 if (likely(HAVE_IP(6) && HAVE_OP(4))) {
218 COPY4(op, ip); 198 COPY4(op, ip);
219 op += t; 199 op += t;
220 ip += t; 200 ip += t;
221 } else 201 } else
222#endif 202#endif
223 { 203 {
224 NEED_IP(t, 3); 204 NEED_IP(t + 3);
225 NEED_OP(t, 0); 205 NEED_OP(t);
226 while (t > 0) { 206 while (t > 0) {
227 *op++ = *ip++; 207 *op++ = *ip++;
228 t--; 208 t--;