diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2019-10-26 20:04:34 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2019-10-26 20:04:34 +0200 |
commit | caf5ee0dd9250a4ca913691bcdc247f8fe814e22 (patch) | |
tree | e65eae8ef6aec65f1e9662ad489048fc8e580a12 | |
parent | 122a8cbd4a3053e32bb76e6aa081deb890b10b11 (diff) | |
download | busybox-w32-caf5ee0dd9250a4ca913691bcdc247f8fe814e22.tar.gz busybox-w32-caf5ee0dd9250a4ca913691bcdc247f8fe814e22.tar.bz2 busybox-w32-caf5ee0dd9250a4ca913691bcdc247f8fe814e22.zip |
gunzip: fix incorrect decoding of "fixed" inflate blocks
function old new delta
huft_build 1008 1022 +14
inflate_block 1253 1256 +3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 17/0) Total: 17 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libarchive/decompress_gunzip.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index 0f8173d0a..03049cc9b 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c | |||
@@ -280,11 +280,17 @@ static unsigned fill_bitbuffer(STATE_PARAM unsigned bitbuffer, unsigned *current | |||
280 | * b: code lengths in bits (all assumed <= BMAX) | 280 | * b: code lengths in bits (all assumed <= BMAX) |
281 | * n: number of codes (assumed <= N_MAX) | 281 | * n: number of codes (assumed <= N_MAX) |
282 | * s: number of simple-valued codes (0..s-1) | 282 | * s: number of simple-valued codes (0..s-1) |
283 | * d: list of base values for non-simple codes | 283 | * cp_ext->cp,ext: list of base values/extra bits for non-simple codes |
284 | * e: list of extra bits for non-simple codes | ||
285 | * m: maximum lookup bits, returns actual | 284 | * m: maximum lookup bits, returns actual |
286 | * result: starting table | 285 | * result: starting table |
286 | * | ||
287 | * On error, returns a value with lowest-bit set on error. | ||
288 | * It can be just the value of 0x1, | ||
289 | * or a valid pointer to a Huffman table, ORed with 0x1 if incompete table | ||
290 | * is given: "fixed inflate" decoder feeds us such data. | ||
287 | */ | 291 | */ |
292 | #define BAD_HUFT(p) ((uintptr_t)(p) & 1) | ||
293 | #define ERR_RET ((huft_t*)(uintptr_t)1) | ||
288 | static huft_t* huft_build(const unsigned *b, const unsigned n, | 294 | static huft_t* huft_build(const unsigned *b, const unsigned n, |
289 | const unsigned s, const struct cp_ext *cp_ext, | 295 | const unsigned s, const struct cp_ext *cp_ext, |
290 | unsigned *m) | 296 | unsigned *m) |
@@ -347,11 +353,11 @@ static huft_t* huft_build(const unsigned *b, const unsigned n, | |||
347 | for (y = 1 << j; j < i; j++, y <<= 1) { | 353 | for (y = 1 << j; j < i; j++, y <<= 1) { |
348 | y -= c[j]; | 354 | y -= c[j]; |
349 | if (y < 0) | 355 | if (y < 0) |
350 | return NULL; /* bad input: more codes than bits */ | 356 | return ERR_RET; /* bad input: more codes than bits */ |
351 | } | 357 | } |
352 | y -= c[i]; | 358 | y -= c[i]; |
353 | if (y < 0) | 359 | if (y < 0) |
354 | return NULL; | 360 | return ERR_RET; |
355 | c[i] += y; | 361 | c[i] += y; |
356 | 362 | ||
357 | /* Generate starting offsets into the value table for each length */ | 363 | /* Generate starting offsets into the value table for each length */ |
@@ -378,7 +384,7 @@ static huft_t* huft_build(const unsigned *b, const unsigned n, | |||
378 | } while (++i < n); | 384 | } while (++i < n); |
379 | 385 | ||
380 | /* Generate the Huffman codes and for each, make the table entries */ | 386 | /* Generate the Huffman codes and for each, make the table entries */ |
381 | result = NULL; | 387 | result = ERR_RET; |
382 | t = &result; | 388 | t = &result; |
383 | x[0] = i = 0; /* first Huffman code is zero */ | 389 | x[0] = i = 0; /* first Huffman code is zero */ |
384 | p = v; /* grab values in bit order */ | 390 | p = v; /* grab values in bit order */ |
@@ -472,7 +478,8 @@ static huft_t* huft_build(const unsigned *b, const unsigned n, | |||
472 | *m = ws[1]; | 478 | *m = ws[1]; |
473 | 479 | ||
474 | if (y != 0 && g != 1) /* we were given an incomplete table */ | 480 | if (y != 0 && g != 1) /* we were given an incomplete table */ |
475 | return NULL; | 481 | /* return "result" ORed with 1 */ |
482 | return (void*)((uintptr_t)result | 1); | ||
476 | 483 | ||
477 | return result; | 484 | return result; |
478 | } | 485 | } |
@@ -776,13 +783,16 @@ static int inflate_block(STATE_PARAM smallint *e) | |||
776 | ll[i] = 8; | 783 | ll[i] = 8; |
777 | bl = 7; | 784 | bl = 7; |
778 | inflate_codes_tl = huft_build(ll, 288, 257, &lit, &bl); | 785 | inflate_codes_tl = huft_build(ll, 288, 257, &lit, &bl); |
779 | /* huft_build() never returns error here - we use known data */ | 786 | /* ^^^ never returns error here - we use known data */ |
780 | 787 | ||
781 | /* set up distance table */ | 788 | /* set up distance table */ |
782 | for (i = 0; i < 30; i++) /* make an incomplete code set */ | 789 | for (i = 0; i < 30; i++) /* make an incomplete code set */ |
783 | ll[i] = 5; | 790 | ll[i] = 5; |
784 | bd = 5; | 791 | bd = 5; |
785 | inflate_codes_td = huft_build(ll, 30, 0, &dist, &bd); | 792 | inflate_codes_td = huft_build(ll, 30, 0, &dist, &bd); |
793 | /* ^^^ does return error here! (lsb bit is set) - we gave it incomplete code set */ | ||
794 | /* clearing error bit: */ | ||
795 | inflate_codes_td = (void*)((uintptr_t)inflate_codes_td & ~(uintptr_t)1); | ||
786 | 796 | ||
787 | /* set up data for inflate_codes() */ | 797 | /* set up data for inflate_codes() */ |
788 | inflate_codes_setup(PASS_STATE bl, bd); | 798 | inflate_codes_setup(PASS_STATE bl, bd); |
@@ -849,7 +859,7 @@ static int inflate_block(STATE_PARAM smallint *e) | |||
849 | /* build decoding table for trees - single level, 7 bit lookup */ | 859 | /* build decoding table for trees - single level, 7 bit lookup */ |
850 | bl = 7; | 860 | bl = 7; |
851 | inflate_codes_tl = huft_build(ll, 19, 19, NULL, &bl); | 861 | inflate_codes_tl = huft_build(ll, 19, 19, NULL, &bl); |
852 | if (!inflate_codes_tl) { | 862 | if (BAD_HUFT(inflate_codes_tl)) { |
853 | abort_unzip(PASS_STATE_ONLY); /* incomplete code set */ | 863 | abort_unzip(PASS_STATE_ONLY); /* incomplete code set */ |
854 | } | 864 | } |
855 | 865 | ||
@@ -914,12 +924,12 @@ static int inflate_block(STATE_PARAM smallint *e) | |||
914 | /* build the decoding tables for literal/length and distance codes */ | 924 | /* build the decoding tables for literal/length and distance codes */ |
915 | bl = lbits; | 925 | bl = lbits; |
916 | inflate_codes_tl = huft_build(ll, nl, 257, &lit, &bl); | 926 | inflate_codes_tl = huft_build(ll, nl, 257, &lit, &bl); |
917 | if (!inflate_codes_tl) { | 927 | if (BAD_HUFT(inflate_codes_tl)) { |
918 | abort_unzip(PASS_STATE_ONLY); | 928 | abort_unzip(PASS_STATE_ONLY); |
919 | } | 929 | } |
920 | bd = dbits; | 930 | bd = dbits; |
921 | inflate_codes_td = huft_build(ll + nl, nd, 0, &dist, &bd); | 931 | inflate_codes_td = huft_build(ll + nl, nd, 0, &dist, &bd); |
922 | if (!inflate_codes_td) { | 932 | if (BAD_HUFT(inflate_codes_td)) { |
923 | abort_unzip(PASS_STATE_ONLY); | 933 | abort_unzip(PASS_STATE_ONLY); |
924 | } | 934 | } |
925 | 935 | ||