diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-10-22 18:23:23 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-10-22 18:23:23 +0200 |
commit | 0402cb32df015d9372578e3db27db47b33d5c7b0 (patch) | |
tree | 42434dd16d98f1acd0f53ad5da9673e00214a4fe | |
parent | 25f3b737dc04bb84fb593ace33a5c360163bd4e4 (diff) | |
download | busybox-w32-0402cb32df015d9372578e3db27db47b33d5c7b0.tar.gz busybox-w32-0402cb32df015d9372578e3db27db47b33d5c7b0.tar.bz2 busybox-w32-0402cb32df015d9372578e3db27db47b33d5c7b0.zip |
bunzip2: fix runCnt overflow from bug 10431
This particular corrupted file can be dealth with by using "unsigned".
If there will be cases where it genuinely overflows, there is a disabled
code to deal with that too.
function old new delta
get_next_block 1678 1667 -11
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libarchive/decompress_bunzip2.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index 7cd18f5ed..bec89edd3 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c | |||
@@ -156,15 +156,15 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted) | |||
156 | static int get_next_block(bunzip_data *bd) | 156 | static int get_next_block(bunzip_data *bd) |
157 | { | 157 | { |
158 | struct group_data *hufGroup; | 158 | struct group_data *hufGroup; |
159 | int dbufCount, dbufSize, groupCount, *base, *limit, selector, | 159 | int groupCount, *base, *limit, selector, |
160 | i, j, runPos, symCount, symTotal, nSelectors, byteCount[256]; | 160 | i, j, symCount, symTotal, nSelectors, byteCount[256]; |
161 | int runCnt = runCnt; /* for compiler */ | ||
162 | uint8_t uc, symToByte[256], mtfSymbol[256], *selectors; | 161 | uint8_t uc, symToByte[256], mtfSymbol[256], *selectors; |
163 | uint32_t *dbuf; | 162 | uint32_t *dbuf; |
164 | unsigned origPtr, t; | 163 | unsigned origPtr, t; |
164 | unsigned dbufCount, runPos; | ||
165 | unsigned runCnt = runCnt; /* for compiler */ | ||
165 | 166 | ||
166 | dbuf = bd->dbuf; | 167 | dbuf = bd->dbuf; |
167 | dbufSize = bd->dbufSize; | ||
168 | selectors = bd->selectors; | 168 | selectors = bd->selectors; |
169 | 169 | ||
170 | /* In bbox, we are ok with aborting through setjmp which is set up in start_bunzip */ | 170 | /* In bbox, we are ok with aborting through setjmp which is set up in start_bunzip */ |
@@ -187,7 +187,7 @@ static int get_next_block(bunzip_data *bd) | |||
187 | it didn't actually work. */ | 187 | it didn't actually work. */ |
188 | if (get_bits(bd, 1)) return RETVAL_OBSOLETE_INPUT; | 188 | if (get_bits(bd, 1)) return RETVAL_OBSOLETE_INPUT; |
189 | origPtr = get_bits(bd, 24); | 189 | origPtr = get_bits(bd, 24); |
190 | if ((int)origPtr > dbufSize) return RETVAL_DATA_ERROR; | 190 | if (origPtr > bd->dbufSize) return RETVAL_DATA_ERROR; |
191 | 191 | ||
192 | /* mapping table: if some byte values are never used (encoding things | 192 | /* mapping table: if some byte values are never used (encoding things |
193 | like ascii text), the compression code removes the gaps to have fewer | 193 | like ascii text), the compression code removes the gaps to have fewer |
@@ -435,7 +435,14 @@ static int get_next_block(bunzip_data *bd) | |||
435 | symbols, but a run of length 0 doesn't mean anything in this | 435 | symbols, but a run of length 0 doesn't mean anything in this |
436 | context). Thus space is saved. */ | 436 | context). Thus space is saved. */ |
437 | runCnt += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */ | 437 | runCnt += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */ |
438 | if (runPos < dbufSize) runPos <<= 1; | 438 | //The 32-bit overflow of runCnt wasn't yet seen, but probably can happen. |
439 | //This would be the fix (catches too large count way before it can overflow): | ||
440 | // if (runCnt > bd->dbufSize) { | ||
441 | // dbg("runCnt:%u > dbufSize:%u RETVAL_DATA_ERROR", | ||
442 | // runCnt, bd->dbufSize); | ||
443 | // return RETVAL_DATA_ERROR; | ||
444 | // } | ||
445 | if (runPos < bd->dbufSize) runPos <<= 1; | ||
439 | goto end_of_huffman_loop; | 446 | goto end_of_huffman_loop; |
440 | } | 447 | } |
441 | 448 | ||
@@ -445,14 +452,15 @@ static int get_next_block(bunzip_data *bd) | |||
445 | literal used is the one at the head of the mtfSymbol array.) */ | 452 | literal used is the one at the head of the mtfSymbol array.) */ |
446 | if (runPos != 0) { | 453 | if (runPos != 0) { |
447 | uint8_t tmp_byte; | 454 | uint8_t tmp_byte; |
448 | if (dbufCount + runCnt > dbufSize) { | 455 | if (dbufCount + runCnt > bd->dbufSize) { |
449 | dbg("dbufCount:%d+runCnt:%d %d > dbufSize:%d RETVAL_DATA_ERROR", | 456 | dbg("dbufCount:%u+runCnt:%u %u > dbufSize:%u RETVAL_DATA_ERROR", |
450 | dbufCount, runCnt, dbufCount + runCnt, dbufSize); | 457 | dbufCount, runCnt, dbufCount + runCnt, bd->dbufSize); |
451 | return RETVAL_DATA_ERROR; | 458 | return RETVAL_DATA_ERROR; |
452 | } | 459 | } |
453 | tmp_byte = symToByte[mtfSymbol[0]]; | 460 | tmp_byte = symToByte[mtfSymbol[0]]; |
454 | byteCount[tmp_byte] += runCnt; | 461 | byteCount[tmp_byte] += runCnt; |
455 | while (--runCnt >= 0) dbuf[dbufCount++] = (uint32_t)tmp_byte; | 462 | while ((int)--runCnt >= 0) |
463 | dbuf[dbufCount++] = (uint32_t)tmp_byte; | ||
456 | runPos = 0; | 464 | runPos = 0; |
457 | } | 465 | } |
458 | 466 | ||
@@ -466,7 +474,7 @@ static int get_next_block(bunzip_data *bd) | |||
466 | first symbol in the mtf array, position 0, would have been handled | 474 | first symbol in the mtf array, position 0, would have been handled |
467 | as part of a run above. Therefore 1 unused mtf position minus | 475 | as part of a run above. Therefore 1 unused mtf position minus |
468 | 2 non-literal nextSym values equals -1.) */ | 476 | 2 non-literal nextSym values equals -1.) */ |
469 | if (dbufCount >= dbufSize) return RETVAL_DATA_ERROR; | 477 | if (dbufCount >= bd->dbufSize) return RETVAL_DATA_ERROR; |
470 | i = nextSym - 1; | 478 | i = nextSym - 1; |
471 | uc = mtfSymbol[i]; | 479 | uc = mtfSymbol[i]; |
472 | 480 | ||