Tue Aug 16 13:55:02 2011 UTC ()
Do proper input validation without penalizing performance.


(joerg)
diff -r1.14 -r1.15 src/usr.bin/compress/zopen.c
diff -r1.10 -r1.11 src/usr.bin/gzip/zuncompress.c

cvs diff -r1.14 -r1.15 src/usr.bin/compress/zopen.c (expand / switch to unified diff)

--- src/usr.bin/compress/zopen.c 2011/08/16 03:24:47 1.14
+++ src/usr.bin/compress/zopen.c 2011/08/16 13:55:01 1.15
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: zopen.c,v 1.14 2011/08/16 03:24:47 christos Exp $ */ 1/* $NetBSD: zopen.c,v 1.15 2011/08/16 13:55:01 joerg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1985, 1986, 1992, 1993 4 * Copyright (c) 1985, 1986, 1992, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Diomidis Spinellis and James A. Woods, derived from original 8 * Diomidis Spinellis and James A. Woods, derived from original
9 * work by Spencer Thomas and Joseph Orost. 9 * work by Spencer Thomas and Joseph Orost.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE. 33 * SUCH DAMAGE.
34 */ 34 */
35 35
36#if defined(LIBC_SCCS) && !defined(lint) 36#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 37#if 0
38static char sccsid[] = "@(#)zopen.c 8.1 (Berkeley) 6/27/93"; 38static char sccsid[] = "@(#)zopen.c 8.1 (Berkeley) 6/27/93";
39#else 39#else
40static char rcsid[] = "$NetBSD: zopen.c,v 1.14 2011/08/16 03:24:47 christos Exp $"; 40static char rcsid[] = "$NetBSD: zopen.c,v 1.15 2011/08/16 13:55:01 joerg Exp $";
41#endif 41#endif
42#endif /* LIBC_SCCS and not lint */ 42#endif /* LIBC_SCCS and not lint */
43 43
44/*- 44/*-
45 * fcompress.c - File compression ala IEEE Computer, June 1984. 45 * fcompress.c - File compression ala IEEE Computer, June 1984.
46 * 46 *
47 * Compress authors: 47 * Compress authors:
48 * Spencer W. Thomas (decvax!utah-cs!thomas) 48 * Spencer W. Thomas (decvax!utah-cs!thomas)
49 * Jim McKie (decvax!mcvax!jim) 49 * Jim McKie (decvax!mcvax!jim)
50 * Steve Davies (decvax!vax135!petsd!peora!srd) 50 * Steve Davies (decvax!vax135!petsd!peora!srd)
51 * Ken Turkowski (decvax!decwrl!turtlevax!ken) 51 * Ken Turkowski (decvax!decwrl!turtlevax!ken)
52 * James A. Woods (decvax!ihnp4!ames!jaw) 52 * James A. Woods (decvax!ihnp4!ames!jaw)
53 * Joe Orost (decvax!vax135!petsd!joe) 53 * Joe Orost (decvax!vax135!petsd!joe)
@@ -476,85 +476,85 @@ zread(void *cookie, char *rbp, int num) @@ -476,85 +476,85 @@ zread(void *cookie, char *rbp, int num)
476 } 476 }
477 477
478 /* Check the magic number */ 478 /* Check the magic number */
479 if (fread(header, 479 if (fread(header,
480 sizeof(char), sizeof(header), fp) != sizeof(header) || 480 sizeof(char), sizeof(header), fp) != sizeof(header) ||
481 memcmp(header, magic_header, sizeof(magic_header)) != 0) { 481 memcmp(header, magic_header, sizeof(magic_header)) != 0) {
482 errno = EFTYPE; 482 errno = EFTYPE;
483 return (-1); 483 return (-1);
484 } 484 }
485 maxbits = header[2]; /* Set -b from file. */ 485 maxbits = header[2]; /* Set -b from file. */
486 block_compress = maxbits & BLOCK_MASK; 486 block_compress = maxbits & BLOCK_MASK;
487 maxbits &= BIT_MASK; 487 maxbits &= BIT_MASK;
488 maxmaxcode = 1L << maxbits; 488 maxmaxcode = 1L << maxbits;
489 if (maxbits > BITS) { 489 if (maxbits > BITS || maxbits < 12) {
490 errno = EFTYPE; 490 errno = EFTYPE;
491 return (-1); 491 return (-1);
492 } 492 }
493 /* As above, initialize the first 256 entries in the table. */ 493 /* As above, initialize the first 256 entries in the table. */
494 maxcode = MAXCODE(n_bits = INIT_BITS); 494 maxcode = MAXCODE(n_bits = INIT_BITS);
495 for (code = 255; code >= 0; code--) { 495 for (code = 255; code >= 0; code--) {
496 tab_prefixof(code) = 0; 496 tab_prefixof(code) = 0;
497 tab_suffixof(code) = (char_type) code; 497 tab_suffixof(code) = (char_type) code;
498 } 498 }
499 free_ent = block_compress ? FIRST : 256; 499 free_ent = block_compress ? FIRST : 256;
500 500 oldcode = -1;
501 finchar = oldcode = getcode(zs); 
502 if (oldcode == -1) /* EOF already? */ 
503 return (0); /* Get out of here */ 
504 
505 /* First code must be 8 bits = char. */ 
506 *bp++ = (u_char)finchar; 
507 count--; 
508 stackp = de_stack; 501 stackp = de_stack;
509 502
510 while ((code = getcode(zs)) > -1) { 503 while ((code = getcode(zs)) > -1) {
511 504
512 if ((code == CLEAR) && block_compress) { 505 if ((code == CLEAR) && block_compress) {
513 for (code = 255; code >= 0; code--) 506 for (code = 255; code >= 0; code--)
514 tab_prefixof(code) = 0; 507 tab_prefixof(code) = 0;
515 clear_flg = 1; 508 clear_flg = 1;
516 free_ent = FIRST - 1; 509 free_ent = FIRST;
517 if ((code = getcode(zs)) == -1) /* O, untimely death! */ 510 oldcode = -1;
518 break; 511 continue;
519 } 512 }
520 incode = code; 513 incode = code;
521 514
522 /* Special case FOR kWkWk string. */ 515 /* Special case for kWkWk string. */
523 if (code >= free_ent) { 516 if (code >= free_ent) {
 517 if (code > free_ent || oldcode == -1) {
 518 /* Bad stream. */
 519 errno = EINVAL;
 520 return (-1);
 521 }
524 *stackp++ = finchar; 522 *stackp++ = finchar;
525 code = oldcode; 523 code = oldcode;
526 } 524 }
 525 /*
 526 * The above condition ensures that code < free_ent.
 527 * The construction of tab_prefixof in turn guarantees that
 528 * each iteration decreases code and therefore stack usage is
 529 * bound by 1 << BITS - 256.
 530 */
527 531
528 /* Generate output characters in reverse order. */ 532 /* Generate output characters in reverse order. */
529 while (code >= 256) { 533 while (code >= 256) {
530 if (stackp - de_stack >= HSIZE - 1) { 
531 errno = EOVERFLOW; 
532 return -1; 
533 } 
534 *stackp++ = tab_suffixof(code); 534 *stackp++ = tab_suffixof(code);
535 code = tab_prefixof(code); 535 code = tab_prefixof(code);
536 } 536 }
537 *stackp++ = finchar = tab_suffixof(code); 537 *stackp++ = finchar = tab_suffixof(code);
538 538
539 /* And put them out in forward order. */ 539 /* And put them out in forward order. */
540middle: do { 540middle: do {
541 if (count-- == 0) 541 if (count-- == 0)
542 return (num); 542 return (num);
543 *bp++ = *--stackp; 543 *bp++ = *--stackp;
544 } while (stackp > de_stack); 544 } while (stackp > de_stack);
545 545
546 /* Generate the new entry. */ 546 /* Generate the new entry. */
547 if ((code = free_ent) < maxmaxcode) { 547 if ((code = free_ent) < maxmaxcode && oldcode != -1) {
548 tab_prefixof(code) = (u_short) oldcode; 548 tab_prefixof(code) = (u_short) oldcode;
549 tab_suffixof(code) = finchar; 549 tab_suffixof(code) = finchar;
550 free_ent = code + 1; 550 free_ent = code + 1;
551 } 551 }
552 552
553 /* Remember previous code. */ 553 /* Remember previous code. */
554 oldcode = incode; 554 oldcode = incode;
555 } 555 }
556 state = S_EOF; 556 state = S_EOF;
557eof: return (num - count); 557eof: return (num - count);
558} 558}
559 559
560/*- 560/*-

cvs diff -r1.10 -r1.11 src/usr.bin/gzip/zuncompress.c (expand / switch to unified diff)

--- src/usr.bin/gzip/zuncompress.c 2011/08/16 03:25:34 1.10
+++ src/usr.bin/gzip/zuncompress.c 2011/08/16 13:55:02 1.11
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: zuncompress.c,v 1.10 2011/08/16 03:25:34 christos Exp $ */ 1/* $NetBSD: zuncompress.c,v 1.11 2011/08/16 13:55:02 joerg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1985, 1986, 1992, 1993 4 * Copyright (c) 1985, 1986, 1992, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Diomidis Spinellis and James A. Woods, derived from original 8 * Diomidis Spinellis and James A. Woods, derived from original
9 * work by Spencer Thomas and Joseph Orost. 9 * work by Spencer Thomas and Joseph Orost.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -236,86 +236,89 @@ zread(void *cookie, char *rbp, int num) @@ -236,86 +236,89 @@ zread(void *cookie, char *rbp, int num)
236 header[i] = *compressed_pre++; 236 header[i] = *compressed_pre++;
237 237
238 if (fread(header + i, 1, sizeof(header) - i, zs->zs_fp) != 238 if (fread(header + i, 1, sizeof(header) - i, zs->zs_fp) !=
239 sizeof(header) - i || 239 sizeof(header) - i ||
240 memcmp(header, magic_header, sizeof(magic_header)) != 0) { 240 memcmp(header, magic_header, sizeof(magic_header)) != 0) {
241 errno = EFTYPE; 241 errno = EFTYPE;
242 return (-1); 242 return (-1);
243 } 243 }
244 total_compressed_bytes = 0; 244 total_compressed_bytes = 0;
245 zs->zs_maxbits = header[2]; /* Set -b from file. */ 245 zs->zs_maxbits = header[2]; /* Set -b from file. */
246 zs->zs_block_compress = zs->zs_maxbits & BLOCK_MASK; 246 zs->zs_block_compress = zs->zs_maxbits & BLOCK_MASK;
247 zs->zs_maxbits &= BIT_MASK; 247 zs->zs_maxbits &= BIT_MASK;
248 zs->zs_maxmaxcode = 1L << zs->zs_maxbits; 248 zs->zs_maxmaxcode = 1L << zs->zs_maxbits;
249 if (zs->zs_maxbits > BITS) { 249 if (zs->zs_maxbits > BITS || zs->zs_maxbits < 12) {
250 errno = EFTYPE; 250 errno = EFTYPE;
251 return (-1); 251 return (-1);
252 } 252 }
253 /* As above, initialize the first 256 entries in the table. */ 253 /* As above, initialize the first 256 entries in the table. */
254 zs->zs_maxcode = MAXCODE(zs->zs_n_bits = INIT_BITS); 254 zs->zs_maxcode = MAXCODE(zs->zs_n_bits = INIT_BITS);
255 for (zs->u.r.zs_code = 255; zs->u.r.zs_code >= 0; zs->u.r.zs_code--) { 255 for (zs->u.r.zs_code = 255; zs->u.r.zs_code >= 0; zs->u.r.zs_code--) {
256 tab_prefixof(zs->u.r.zs_code) = 0; 256 tab_prefixof(zs->u.r.zs_code) = 0;
257 tab_suffixof(zs->u.r.zs_code) = (char_type) zs->u.r.zs_code; 257 tab_suffixof(zs->u.r.zs_code) = (char_type) zs->u.r.zs_code;
258 } 258 }
259 zs->zs_free_ent = zs->zs_block_compress ? FIRST : 256; 259 zs->zs_free_ent = zs->zs_block_compress ? FIRST : 256;
260 260
261 zs->u.r.zs_finchar = zs->u.r.zs_oldcode = getcode(zs); 261 zs->u.r.zs_oldcode = -1;
262 if (zs->u.r.zs_oldcode == -1) /* EOF already? */ 
263 return (0); /* Get out of here */ 
264 
265 /* First code must be 8 bits = char. */ 
266 *bp++ = (u_char)zs->u.r.zs_finchar; 
267 count--; 
268 zs->u.r.zs_stackp = de_stack; 262 zs->u.r.zs_stackp = de_stack;
269 263
270 while ((zs->u.r.zs_code = getcode(zs)) > -1) { 264 while ((zs->u.r.zs_code = getcode(zs)) > -1) {
271 265
272 if ((zs->u.r.zs_code == CLEAR) && zs->zs_block_compress) { 266 if ((zs->u.r.zs_code == CLEAR) && zs->zs_block_compress) {
273 for (zs->u.r.zs_code = 255; zs->u.r.zs_code >= 0; 267 for (zs->u.r.zs_code = 255; zs->u.r.zs_code >= 0;
274 zs->u.r.zs_code--) 268 zs->u.r.zs_code--)
275 tab_prefixof(zs->u.r.zs_code) = 0; 269 tab_prefixof(zs->u.r.zs_code) = 0;
276 zs->zs_clear_flg = 1; 270 zs->zs_clear_flg = 1;
277 zs->zs_free_ent = FIRST - 1; 271 zs->zs_free_ent = FIRST;
278 if ((zs->u.r.zs_code = getcode(zs)) == -1) /* O, untimely death! */ 272 zs->u.r.zs_oldcode = -1;
279 break; 273 continue;
280 } 274 }
281 zs->u.r.zs_incode = zs->u.r.zs_code; 275 zs->u.r.zs_incode = zs->u.r.zs_code;
282 276
283 /* Special case for KwKwK string. */ 277 /* Special case for KwKwK string. */
284 if (zs->u.r.zs_code >= zs->zs_free_ent) { 278 if (zs->u.r.zs_code >= zs->zs_free_ent) {
 279 if (zs->u.r.zs_code > zs->zs_free_ent ||
 280 zs->u.r.zs_oldcode == -1) {
 281 /* Bad stream. */
 282 errno = EINVAL;
 283 return (-1);
 284 }
285 *zs->u.r.zs_stackp++ = zs->u.r.zs_finchar; 285 *zs->u.r.zs_stackp++ = zs->u.r.zs_finchar;
286 zs->u.r.zs_code = zs->u.r.zs_oldcode; 286 zs->u.r.zs_code = zs->u.r.zs_oldcode;
287 } 287 }
 288 /*
 289 * The above condition ensures that code < free_ent.
 290 * The construction of tab_prefixof in turn guarantees that
 291 * each iteration decreases code and therefore stack usage is
 292 * bound by 1 << BITS - 256.
 293 */
288 294
289 /* Generate output characters in reverse order. */ 295 /* Generate output characters in reverse order. */
290 while (zs->u.r.zs_code >= 256) { 296 while (zs->u.r.zs_code >= 256) {
291 if (zs->u.r.zs_stackp - de_stack >= HSIZE - 1) { 
292 errno = EOVERFLOW; 
293 return -1; 
294 } 
295 *zs->u.r.zs_stackp++ = tab_suffixof(zs->u.r.zs_code); 297 *zs->u.r.zs_stackp++ = tab_suffixof(zs->u.r.zs_code);
296 zs->u.r.zs_code = tab_prefixof(zs->u.r.zs_code); 298 zs->u.r.zs_code = tab_prefixof(zs->u.r.zs_code);
297 } 299 }
298 *zs->u.r.zs_stackp++ = zs->u.r.zs_finchar = tab_suffixof(zs->u.r.zs_code); 300 *zs->u.r.zs_stackp++ = zs->u.r.zs_finchar = tab_suffixof(zs->u.r.zs_code);
299 301
300 /* And put them out in forward order. */ 302 /* And put them out in forward order. */
301middle: do { 303middle: do {
302 if (count-- == 0) 304 if (count-- == 0)
303 return (num); 305 return (num);
304 *bp++ = *--zs->u.r.zs_stackp; 306 *bp++ = *--zs->u.r.zs_stackp;
305 } while (zs->u.r.zs_stackp > de_stack); 307 } while (zs->u.r.zs_stackp > de_stack);
306 308
307 /* Generate the new entry. */ 309 /* Generate the new entry. */
308 if ((zs->u.r.zs_code = zs->zs_free_ent) < zs->zs_maxmaxcode) { 310 if ((zs->u.r.zs_code = zs->zs_free_ent) < zs->zs_maxmaxcode &&
 311 zs->u.r.zs_oldcode != -1) {
309 tab_prefixof(zs->u.r.zs_code) = (u_short) zs->u.r.zs_oldcode; 312 tab_prefixof(zs->u.r.zs_code) = (u_short) zs->u.r.zs_oldcode;
310 tab_suffixof(zs->u.r.zs_code) = zs->u.r.zs_finchar; 313 tab_suffixof(zs->u.r.zs_code) = zs->u.r.zs_finchar;
311 zs->zs_free_ent = zs->u.r.zs_code + 1; 314 zs->zs_free_ent = zs->u.r.zs_code + 1;
312 } 315 }
313 316
314 /* Remember previous code. */ 317 /* Remember previous code. */
315 zs->u.r.zs_oldcode = zs->u.r.zs_incode; 318 zs->u.r.zs_oldcode = zs->u.r.zs_incode;
316 } 319 }
317 zs->zs_state = S_EOF; 320 zs->zs_state = S_EOF;
318eof: return (num - count); 321eof: return (num - count);
319} 322}
320 323
321/*- 324/*-