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 ;
@@ -116,25 +128,32 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
116
128
if (t != 0 ) {
117
129
if (t <= 3 ) {
118
130
op [* state_offset ] |= t ;
131
+ NEED_OP (4 );
119
132
COPY4 (op , ii );
120
133
op += t ;
121
134
} else if (t <= 16 ) {
135
+ NEED_OP (17 );
122
136
* op ++ = (t - 3 );
123
137
COPY8 (op , ii );
124
138
COPY8 (op + 8 , ii + 8 );
125
139
op += t ;
126
140
} else {
127
141
if (t <= 18 ) {
142
+ NEED_OP (1 );
128
143
* op ++ = (t - 3 );
129
144
} else {
130
145
size_t tt = t - 18 ;
146
+ NEED_OP (1 );
131
147
* op ++ = 0 ;
132
148
while (unlikely (tt > 255 )) {
133
149
tt -= 255 ;
150
+ NEED_OP (1 );
134
151
* op ++ = 0 ;
135
152
}
153
+ NEED_OP (1 );
136
154
* op ++ = tt ;
137
155
}
156
+ NEED_OP (t );
138
157
do {
139
158
COPY8 (op , ii );
140
159
COPY8 (op + 8 , ii + 8 );
@@ -151,6 +170,7 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
151
170
if (unlikely (run_length )) {
152
171
ip += run_length ;
153
172
run_length -= MIN_ZERO_RUN_LENGTH ;
173
+ NEED_OP (4 );
154
174
put_unaligned_le32 ((run_length << 21 ) | 0xfffc18
155
175
| (run_length & 0x7 ), op );
156
176
op += 4 ;
@@ -243,25 +263,31 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
243
263
ip += m_len ;
244
264
if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET ) {
245
265
m_off -= 1 ;
266
+ NEED_OP (2 );
246
267
* op ++ = (((m_len - 1 ) << 5 ) | ((m_off & 7 ) << 2 ));
247
268
* op ++ = (m_off >> 3 );
248
269
} else if (m_off <= M3_MAX_OFFSET ) {
249
270
m_off -= 1 ;
271
+ NEED_OP (1 );
250
272
if (m_len <= M3_MAX_LEN )
251
273
* op ++ = (M3_MARKER | (m_len - 2 ));
252
274
else {
253
275
m_len -= M3_MAX_LEN ;
254
276
* op ++ = M3_MARKER | 0 ;
255
277
while (unlikely (m_len > 255 )) {
256
278
m_len -= 255 ;
279
+ NEED_OP (1 );
257
280
* op ++ = 0 ;
258
281
}
282
+ NEED_OP (1 );
259
283
* op ++ = (m_len );
260
284
}
285
+ NEED_OP (2 );
261
286
* op ++ = (m_off << 2 );
262
287
* op ++ = (m_off >> 6 );
263
288
} else {
264
289
m_off -= 0x4000 ;
290
+ NEED_OP (1 );
265
291
if (m_len <= M4_MAX_LEN )
266
292
* op ++ = (M4_MARKER | ((m_off >> 11 ) & 8 )
267
293
| (m_len - 2 ));
@@ -282,11 +308,14 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
282
308
m_len -= M4_MAX_LEN ;
283
309
* op ++ = (M4_MARKER | ((m_off >> 11 ) & 8 ));
284
310
while (unlikely (m_len > 255 )) {
311
+ NEED_OP (1 );
285
312
m_len -= 255 ;
286
313
* op ++ = 0 ;
287
314
}
315
+ NEED_OP (1 );
288
316
* op ++ = (m_len );
289
317
}
318
+ NEED_OP (2 );
290
319
* op ++ = (m_off << 2 );
291
320
* op ++ = (m_off >> 6 );
292
321
}
@@ -295,14 +324,20 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
295
324
ii = ip ;
296
325
goto next ;
297
326
}
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 ;
300
333
}
301
334
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 )
305
339
{
340
+ unsigned char * const op_end = out + * out_len ;
306
341
const unsigned char * ip = in ;
307
342
unsigned char * op = out ;
308
343
unsigned char * data_start ;
@@ -326,14 +361,18 @@ static int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len,
326
361
while (l > 20 ) {
327
362
size_t ll = min_t (size_t , l , m4_max_offset + 1 );
328
363
uintptr_t ll_end = (uintptr_t ) ip + ll ;
364
+ int err ;
365
+
329
366
if ((ll_end + ((t + ll ) >> 5 )) <= ll_end )
330
367
break ;
331
368
BUILD_BUG_ON (D_SIZE * sizeof (lzo_dict_t ) > LZO1X_1_MEM_COMPRESS );
332
369
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 ;
335
375
ip += ll ;
336
- op += * out_len ;
337
376
l -= ll ;
338
377
}
339
378
t += l ;
@@ -342,20 +381,26 @@ static int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len,
342
381
const unsigned char * ii = in + in_len - t ;
343
382
344
383
if (op == data_start && t <= 238 ) {
384
+ NEED_OP (1 );
345
385
* op ++ = (17 + t );
346
386
} else if (t <= 3 ) {
347
387
op [state_offset ] |= t ;
348
388
} else if (t <= 18 ) {
389
+ NEED_OP (1 );
349
390
* op ++ = (t - 3 );
350
391
} else {
351
392
size_t tt = t - 18 ;
393
+ NEED_OP (1 );
352
394
* op ++ = 0 ;
353
395
while (tt > 255 ) {
354
396
tt -= 255 ;
397
+ NEED_OP (1 );
355
398
* op ++ = 0 ;
356
399
}
400
+ NEED_OP (1 );
357
401
* op ++ = tt ;
358
402
}
403
+ NEED_OP (t );
359
404
if (t >= 16 ) do {
360
405
COPY8 (op , ii );
361
406
COPY8 (op + 8 , ii + 8 );
@@ -368,31 +413,38 @@ static int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len,
368
413
} while (-- t > 0 );
369
414
}
370
415
416
+ NEED_OP (3 );
371
417
* op ++ = M4_MARKER | 1 ;
372
418
* op ++ = 0 ;
373
419
* op ++ = 0 ;
374
420
375
421
* out_len = op - out ;
376
422
return LZO_E_OK ;
423
+
424
+ output_overrun :
425
+ return LZO_E_OUTPUT_OVERRUN ;
377
426
}
378
427
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 )
382
431
{
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 );
384
434
}
385
435
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 )
389
439
{
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 );
392
442
}
393
443
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 ) );
396
446
447
+ #ifndef LZO_UNSAFE
397
448
MODULE_LICENSE ("GPL" );
398
449
MODULE_DESCRIPTION ("LZO1X-1 Compressor" );
450
+ #endif
0 commit comments