1818#include <linux/lzo.h>
1919#include "lzodefs.h"
2020
21- static noinline size_t
22- lzo1x_1_do_compress (const unsigned char * in , size_t in_len ,
23- unsigned char * out , size_t * out_len ,
24- size_t ti , void * wrkmem , signed char * state_offset ,
25- const unsigned char bitstream_version )
21+ #undef LZO_UNSAFE
22+
23+ #ifndef LZO_SAFE
24+ #define LZO_UNSAFE 1
25+ #define LZO_SAFE (name ) name
26+ #define HAVE_OP (x ) 1
27+ #endif
28+
29+ #define NEED_OP (x ) if (!HAVE_OP(x)) goto output_overrun
30+
31+ static noinline int
32+ LZO_SAFE (lzo1x_1_do_compress )(const unsigned char * in , size_t in_len ,
33+ unsigned char * * out , unsigned char * op_end ,
34+ size_t * tp , void * wrkmem ,
35+ signed char * state_offset ,
36+ const unsigned char bitstream_version )
2637{
2738 const unsigned char * ip ;
2839 unsigned char * op ;
2940 const unsigned char * const in_end = in + in_len ;
3041 const unsigned char * const ip_end = in + in_len - 20 ;
3142 const unsigned char * ii ;
3243 lzo_dict_t * const dict = (lzo_dict_t * ) wrkmem ;
44+ size_t ti = * tp ;
3345
34- op = out ;
46+ op = * out ;
3547 ip = in ;
3648 ii = ip ;
3749 ip += ti < 4 ? 4 - ti : 0 ;
@@ -116,25 +128,32 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
116128 if (t != 0 ) {
117129 if (t <= 3 ) {
118130 op [* state_offset ] |= t ;
131+ NEED_OP (4 );
119132 COPY4 (op , ii );
120133 op += t ;
121134 } else if (t <= 16 ) {
135+ NEED_OP (17 );
122136 * op ++ = (t - 3 );
123137 COPY8 (op , ii );
124138 COPY8 (op + 8 , ii + 8 );
125139 op += t ;
126140 } else {
127141 if (t <= 18 ) {
142+ NEED_OP (1 );
128143 * op ++ = (t - 3 );
129144 } else {
130145 size_t tt = t - 18 ;
146+ NEED_OP (1 );
131147 * op ++ = 0 ;
132148 while (unlikely (tt > 255 )) {
133149 tt -= 255 ;
150+ NEED_OP (1 );
134151 * op ++ = 0 ;
135152 }
153+ NEED_OP (1 );
136154 * op ++ = tt ;
137155 }
156+ NEED_OP (t );
138157 do {
139158 COPY8 (op , ii );
140159 COPY8 (op + 8 , ii + 8 );
@@ -151,6 +170,7 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
151170 if (unlikely (run_length )) {
152171 ip += run_length ;
153172 run_length -= MIN_ZERO_RUN_LENGTH ;
173+ NEED_OP (4 );
154174 put_unaligned_le32 ((run_length << 21 ) | 0xfffc18
155175 | (run_length & 0x7 ), op );
156176 op += 4 ;
@@ -243,25 +263,31 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
243263 ip += m_len ;
244264 if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET ) {
245265 m_off -= 1 ;
266+ NEED_OP (2 );
246267 * op ++ = (((m_len - 1 ) << 5 ) | ((m_off & 7 ) << 2 ));
247268 * op ++ = (m_off >> 3 );
248269 } else if (m_off <= M3_MAX_OFFSET ) {
249270 m_off -= 1 ;
271+ NEED_OP (1 );
250272 if (m_len <= M3_MAX_LEN )
251273 * op ++ = (M3_MARKER | (m_len - 2 ));
252274 else {
253275 m_len -= M3_MAX_LEN ;
254276 * op ++ = M3_MARKER | 0 ;
255277 while (unlikely (m_len > 255 )) {
256278 m_len -= 255 ;
279+ NEED_OP (1 );
257280 * op ++ = 0 ;
258281 }
282+ NEED_OP (1 );
259283 * op ++ = (m_len );
260284 }
285+ NEED_OP (2 );
261286 * op ++ = (m_off << 2 );
262287 * op ++ = (m_off >> 6 );
263288 } else {
264289 m_off -= 0x4000 ;
290+ NEED_OP (1 );
265291 if (m_len <= M4_MAX_LEN )
266292 * op ++ = (M4_MARKER | ((m_off >> 11 ) & 8 )
267293 | (m_len - 2 ));
@@ -282,11 +308,14 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
282308 m_len -= M4_MAX_LEN ;
283309 * op ++ = (M4_MARKER | ((m_off >> 11 ) & 8 ));
284310 while (unlikely (m_len > 255 )) {
311+ NEED_OP (1 );
285312 m_len -= 255 ;
286313 * op ++ = 0 ;
287314 }
315+ NEED_OP (1 );
288316 * op ++ = (m_len );
289317 }
318+ NEED_OP (2 );
290319 * op ++ = (m_off << 2 );
291320 * op ++ = (m_off >> 6 );
292321 }
@@ -295,14 +324,20 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
295324 ii = ip ;
296325 goto next ;
297326 }
298- * out_len = op - out ;
299- return in_end - (ii - ti );
327+ * out = op ;
328+ * tp = in_end - (ii - ti );
329+ return LZO_E_OK ;
330+
331+ output_overrun :
332+ return LZO_E_OUTPUT_OVERRUN ;
300333}
301334
302- static int lzogeneric1x_1_compress (const unsigned char * in , size_t in_len ,
303- unsigned char * out , size_t * out_len ,
304- void * wrkmem , const unsigned char bitstream_version )
335+ static int LZO_SAFE (lzogeneric1x_1_compress )(
336+ const unsigned char * in , size_t in_len ,
337+ unsigned char * out , size_t * out_len ,
338+ void * wrkmem , const unsigned char bitstream_version )
305339{
340+ unsigned char * const op_end = out + * out_len ;
306341 const unsigned char * ip = in ;
307342 unsigned char * op = out ;
308343 unsigned char * data_start ;
@@ -326,14 +361,18 @@ static int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len,
326361 while (l > 20 ) {
327362 size_t ll = min_t (size_t , l , m4_max_offset + 1 );
328363 uintptr_t ll_end = (uintptr_t ) ip + ll ;
364+ int err ;
365+
329366 if ((ll_end + ((t + ll ) >> 5 )) <= ll_end )
330367 break ;
331368 BUILD_BUG_ON (D_SIZE * sizeof (lzo_dict_t ) > LZO1X_1_MEM_COMPRESS );
332369 memset (wrkmem , 0 , D_SIZE * sizeof (lzo_dict_t ));
333- t = lzo1x_1_do_compress (ip , ll , op , out_len , t , wrkmem ,
334- & state_offset , bitstream_version );
370+ err = LZO_SAFE (lzo1x_1_do_compress )(
371+ ip , ll , & op , op_end , & t , wrkmem ,
372+ & state_offset , bitstream_version );
373+ if (err != LZO_E_OK )
374+ return err ;
335375 ip += ll ;
336- op += * out_len ;
337376 l -= ll ;
338377 }
339378 t += l ;
@@ -342,20 +381,26 @@ static int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len,
342381 const unsigned char * ii = in + in_len - t ;
343382
344383 if (op == data_start && t <= 238 ) {
384+ NEED_OP (1 );
345385 * op ++ = (17 + t );
346386 } else if (t <= 3 ) {
347387 op [state_offset ] |= t ;
348388 } else if (t <= 18 ) {
389+ NEED_OP (1 );
349390 * op ++ = (t - 3 );
350391 } else {
351392 size_t tt = t - 18 ;
393+ NEED_OP (1 );
352394 * op ++ = 0 ;
353395 while (tt > 255 ) {
354396 tt -= 255 ;
397+ NEED_OP (1 );
355398 * op ++ = 0 ;
356399 }
400+ NEED_OP (1 );
357401 * op ++ = tt ;
358402 }
403+ NEED_OP (t );
359404 if (t >= 16 ) do {
360405 COPY8 (op , ii );
361406 COPY8 (op + 8 , ii + 8 );
@@ -368,31 +413,38 @@ static int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len,
368413 } while (-- t > 0 );
369414 }
370415
416+ NEED_OP (3 );
371417 * op ++ = M4_MARKER | 1 ;
372418 * op ++ = 0 ;
373419 * op ++ = 0 ;
374420
375421 * out_len = op - out ;
376422 return LZO_E_OK ;
423+
424+ output_overrun :
425+ return LZO_E_OUTPUT_OVERRUN ;
377426}
378427
379- int lzo1x_1_compress (const unsigned char * in , size_t in_len ,
380- unsigned char * out , size_t * out_len ,
381- void * wrkmem )
428+ int LZO_SAFE ( lzo1x_1_compress ) (const unsigned char * in , size_t in_len ,
429+ unsigned char * out , size_t * out_len ,
430+ void * wrkmem )
382431{
383- return lzogeneric1x_1_compress (in , in_len , out , out_len , wrkmem , 0 );
432+ return LZO_SAFE (lzogeneric1x_1_compress )(
433+ in , in_len , out , out_len , wrkmem , 0 );
384434}
385435
386- int lzorle1x_1_compress (const unsigned char * in , size_t in_len ,
387- unsigned char * out , size_t * out_len ,
388- void * wrkmem )
436+ int LZO_SAFE ( lzorle1x_1_compress ) (const unsigned char * in , size_t in_len ,
437+ unsigned char * out , size_t * out_len ,
438+ void * wrkmem )
389439{
390- return lzogeneric1x_1_compress ( in , in_len , out , out_len ,
391- wrkmem , LZO_VERSION );
440+ return LZO_SAFE ( lzogeneric1x_1_compress )(
441+ in , in_len , out , out_len , wrkmem , LZO_VERSION );
392442}
393443
394- EXPORT_SYMBOL_GPL (lzo1x_1_compress );
395- EXPORT_SYMBOL_GPL (lzorle1x_1_compress );
444+ EXPORT_SYMBOL_GPL (LZO_SAFE ( lzo1x_1_compress ) );
445+ EXPORT_SYMBOL_GPL (LZO_SAFE ( lzorle1x_1_compress ) );
396446
447+ #ifndef LZO_UNSAFE
397448MODULE_LICENSE ("GPL" );
398449MODULE_DESCRIPTION ("LZO1X-1 Compressor" );
450+ #endif
0 commit comments