18
18
#include <linux/lzo.h>
19
19
#include "lzodefs.h"
20
20
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 )
26
37
{
27
38
const unsigned char * ip ;
28
39
unsigned char * op ;
29
40
const unsigned char * const in_end = in + in_len ;
30
41
const unsigned char * const ip_end = in + in_len - 20 ;
31
42
const unsigned char * ii ;
32
43
lzo_dict_t * const dict = (lzo_dict_t * ) wrkmem ;
44
+ size_t ti = * tp ;
33
45
34
- op = out ;
46
+ op = * out ;
35
47
ip = in ;
36
48
ii = ip ;
37
49
ip += ti < 4 ? 4 - ti : 0 ;
@@ -118,25 +130,32 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
118
130
if (t != 0 ) {
119
131
if (t <= 3 ) {
120
132
op [* state_offset ] |= t ;
133
+ NEED_OP (4 );
121
134
COPY4 (op , ii );
122
135
op += t ;
123
136
} else if (t <= 16 ) {
137
+ NEED_OP (17 );
124
138
* op ++ = (t - 3 );
125
139
COPY8 (op , ii );
126
140
COPY8 (op + 8 , ii + 8 );
127
141
op += t ;
128
142
} else {
129
143
if (t <= 18 ) {
144
+ NEED_OP (1 );
130
145
* op ++ = (t - 3 );
131
146
} else {
132
147
size_t tt = t - 18 ;
148
+ NEED_OP (1 );
133
149
* op ++ = 0 ;
134
150
while (unlikely (tt > 255 )) {
135
151
tt -= 255 ;
152
+ NEED_OP (1 );
136
153
* op ++ = 0 ;
137
154
}
155
+ NEED_OP (1 );
138
156
* op ++ = tt ;
139
157
}
158
+ NEED_OP (t );
140
159
do {
141
160
COPY8 (op , ii );
142
161
COPY8 (op + 8 , ii + 8 );
@@ -153,6 +172,7 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
153
172
if (unlikely (run_length )) {
154
173
ip += run_length ;
155
174
run_length -= MIN_ZERO_RUN_LENGTH ;
175
+ NEED_OP (4 );
156
176
put_unaligned_le32 ((run_length << 21 ) | 0xfffc18
157
177
| (run_length & 0x7 ), op );
158
178
op += 4 ;
@@ -245,25 +265,31 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
245
265
ip += m_len ;
246
266
if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET ) {
247
267
m_off -= 1 ;
268
+ NEED_OP (2 );
248
269
* op ++ = (((m_len - 1 ) << 5 ) | ((m_off & 7 ) << 2 ));
249
270
* op ++ = (m_off >> 3 );
250
271
} else if (m_off <= M3_MAX_OFFSET ) {
251
272
m_off -= 1 ;
273
+ NEED_OP (1 );
252
274
if (m_len <= M3_MAX_LEN )
253
275
* op ++ = (M3_MARKER | (m_len - 2 ));
254
276
else {
255
277
m_len -= M3_MAX_LEN ;
256
278
* op ++ = M3_MARKER | 0 ;
257
279
while (unlikely (m_len > 255 )) {
258
280
m_len -= 255 ;
281
+ NEED_OP (1 );
259
282
* op ++ = 0 ;
260
283
}
284
+ NEED_OP (1 );
261
285
* op ++ = (m_len );
262
286
}
287
+ NEED_OP (2 );
263
288
* op ++ = (m_off << 2 );
264
289
* op ++ = (m_off >> 6 );
265
290
} else {
266
291
m_off -= 0x4000 ;
292
+ NEED_OP (1 );
267
293
if (m_len <= M4_MAX_LEN )
268
294
* op ++ = (M4_MARKER | ((m_off >> 11 ) & 8 )
269
295
| (m_len - 2 ));
@@ -284,11 +310,14 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
284
310
m_len -= M4_MAX_LEN ;
285
311
* op ++ = (M4_MARKER | ((m_off >> 11 ) & 8 ));
286
312
while (unlikely (m_len > 255 )) {
313
+ NEED_OP (1 );
287
314
m_len -= 255 ;
288
315
* op ++ = 0 ;
289
316
}
317
+ NEED_OP (1 );
290
318
* op ++ = (m_len );
291
319
}
320
+ NEED_OP (2 );
292
321
* op ++ = (m_off << 2 );
293
322
* op ++ = (m_off >> 6 );
294
323
}
@@ -297,14 +326,20 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
297
326
ii = ip ;
298
327
goto next ;
299
328
}
300
- * out_len = op - out ;
301
- return in_end - (ii - ti );
329
+ * out = op ;
330
+ * tp = in_end - (ii - ti );
331
+ return LZO_E_OK ;
332
+
333
+ output_overrun :
334
+ return LZO_E_OUTPUT_OVERRUN ;
302
335
}
303
336
304
- static int lzogeneric1x_1_compress (const unsigned char * in , size_t in_len ,
305
- unsigned char * out , size_t * out_len ,
306
- void * wrkmem , const unsigned char bitstream_version )
337
+ static int LZO_SAFE (lzogeneric1x_1_compress )(
338
+ const unsigned char * in , size_t in_len ,
339
+ unsigned char * out , size_t * out_len ,
340
+ void * wrkmem , const unsigned char bitstream_version )
307
341
{
342
+ unsigned char * const op_end = out + * out_len ;
308
343
const unsigned char * ip = in ;
309
344
unsigned char * op = out ;
310
345
unsigned char * data_start ;
@@ -328,14 +363,18 @@ static int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len,
328
363
while (l > 20 ) {
329
364
size_t ll = l <= (m4_max_offset + 1 ) ? l : (m4_max_offset + 1 );
330
365
uintptr_t ll_end = (uintptr_t ) ip + ll ;
366
+ int err ;
367
+
331
368
if ((ll_end + ((t + ll ) >> 5 )) <= ll_end )
332
369
break ;
333
370
BUILD_BUG_ON (D_SIZE * sizeof (lzo_dict_t ) > LZO1X_1_MEM_COMPRESS );
334
371
memset (wrkmem , 0 , D_SIZE * sizeof (lzo_dict_t ));
335
- t = lzo1x_1_do_compress (ip , ll , op , out_len , t , wrkmem ,
336
- & state_offset , bitstream_version );
372
+ err = LZO_SAFE (lzo1x_1_do_compress )(
373
+ ip , ll , & op , op_end , & t , wrkmem ,
374
+ & state_offset , bitstream_version );
375
+ if (err != LZO_E_OK )
376
+ return err ;
337
377
ip += ll ;
338
- op += * out_len ;
339
378
l -= ll ;
340
379
}
341
380
t += l ;
@@ -344,20 +383,26 @@ static int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len,
344
383
const unsigned char * ii = in + in_len - t ;
345
384
346
385
if (op == data_start && t <= 238 ) {
386
+ NEED_OP (1 );
347
387
* op ++ = (17 + t );
348
388
} else if (t <= 3 ) {
349
389
op [state_offset ] |= t ;
350
390
} else if (t <= 18 ) {
391
+ NEED_OP (1 );
351
392
* op ++ = (t - 3 );
352
393
} else {
353
394
size_t tt = t - 18 ;
395
+ NEED_OP (1 );
354
396
* op ++ = 0 ;
355
397
while (tt > 255 ) {
356
398
tt -= 255 ;
399
+ NEED_OP (1 );
357
400
* op ++ = 0 ;
358
401
}
402
+ NEED_OP (1 );
359
403
* op ++ = tt ;
360
404
}
405
+ NEED_OP (t );
361
406
if (t >= 16 ) do {
362
407
COPY8 (op , ii );
363
408
COPY8 (op + 8 , ii + 8 );
@@ -370,31 +415,38 @@ static int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len,
370
415
} while (-- t > 0 );
371
416
}
372
417
418
+ NEED_OP (3 );
373
419
* op ++ = M4_MARKER | 1 ;
374
420
* op ++ = 0 ;
375
421
* op ++ = 0 ;
376
422
377
423
* out_len = op - out ;
378
424
return LZO_E_OK ;
425
+
426
+ output_overrun :
427
+ return LZO_E_OUTPUT_OVERRUN ;
379
428
}
380
429
381
- int lzo1x_1_compress (const unsigned char * in , size_t in_len ,
382
- unsigned char * out , size_t * out_len ,
383
- void * wrkmem )
430
+ int LZO_SAFE ( lzo1x_1_compress ) (const unsigned char * in , size_t in_len ,
431
+ unsigned char * out , size_t * out_len ,
432
+ void * wrkmem )
384
433
{
385
- return lzogeneric1x_1_compress (in , in_len , out , out_len , wrkmem , 0 );
434
+ return LZO_SAFE (lzogeneric1x_1_compress )(
435
+ in , in_len , out , out_len , wrkmem , 0 );
386
436
}
387
437
388
- int lzorle1x_1_compress (const unsigned char * in , size_t in_len ,
389
- unsigned char * out , size_t * out_len ,
390
- void * wrkmem )
438
+ int LZO_SAFE ( lzorle1x_1_compress ) (const unsigned char * in , size_t in_len ,
439
+ unsigned char * out , size_t * out_len ,
440
+ void * wrkmem )
391
441
{
392
- return lzogeneric1x_1_compress ( in , in_len , out , out_len ,
393
- wrkmem , LZO_VERSION );
442
+ return LZO_SAFE ( lzogeneric1x_1_compress )(
443
+ in , in_len , out , out_len , wrkmem , LZO_VERSION );
394
444
}
395
445
396
- EXPORT_SYMBOL_GPL (lzo1x_1_compress );
397
- EXPORT_SYMBOL_GPL (lzorle1x_1_compress );
446
+ EXPORT_SYMBOL_GPL (LZO_SAFE ( lzo1x_1_compress ) );
447
+ EXPORT_SYMBOL_GPL (LZO_SAFE ( lzorle1x_1_compress ) );
398
448
449
+ #ifndef LZO_UNSAFE
399
450
MODULE_LICENSE ("GPL" );
400
451
MODULE_DESCRIPTION ("LZO1X-1 Compressor" );
452
+ #endif
0 commit comments