aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-10-22 18:23:23 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-10-22 18:23:23 +0200
commit0402cb32df015d9372578e3db27db47b33d5c7b0 (patch)
tree42434dd16d98f1acd0f53ad5da9673e00214a4fe
parent25f3b737dc04bb84fb593ace33a5c360163bd4e4 (diff)
downloadbusybox-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.c30
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)
156static int get_next_block(bunzip_data *bd) 156static 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