1 From 0402cb32df015d9372578e3db27db47b33d5c7b0 Mon Sep 17 00:00:00 2001
2 From: Denys Vlasenko <vda.linux@googlemail.com>
3 Date: Sun, 22 Oct 2017 18:23:23 +0200
4 Subject: [PATCH] bunzip2: fix runCnt overflow from bug 10431
6 This particular corrupted file can be dealth with by using "unsigned".
7 If there will be cases where it genuinely overflows, there is a disabled
8 code to deal with that too.
10 function old new delta
11 get_next_block 1678 1667 -11
13 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
14 Signed-off-by: Baruch Siach <baruch@tkos.co.il>
16 Patch status: upstream commit 0402cb32df0
18 archival/libarchive/decompress_bunzip2.c | 30 +++++++++++++++++++-----------
19 1 file changed, 19 insertions(+), 11 deletions(-)
21 diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c
22 index 7cd18f5ed4cf..bec89edd3a4d 100644
23 --- a/archival/libarchive/decompress_bunzip2.c
24 +++ b/archival/libarchive/decompress_bunzip2.c
25 @@ -156,15 +156,15 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted)
26 static int get_next_block(bunzip_data *bd)
28 struct group_data *hufGroup;
29 - int dbufCount, dbufSize, groupCount, *base, *limit, selector,
30 - i, j, runPos, symCount, symTotal, nSelectors, byteCount[256];
31 - int runCnt = runCnt; /* for compiler */
32 + int groupCount, *base, *limit, selector,
33 + i, j, symCount, symTotal, nSelectors, byteCount[256];
34 uint8_t uc, symToByte[256], mtfSymbol[256], *selectors;
37 + unsigned dbufCount, runPos;
38 + unsigned runCnt = runCnt; /* for compiler */
41 - dbufSize = bd->dbufSize;
42 selectors = bd->selectors;
44 /* In bbox, we are ok with aborting through setjmp which is set up in start_bunzip */
45 @@ -187,7 +187,7 @@ static int get_next_block(bunzip_data *bd)
46 it didn't actually work. */
47 if (get_bits(bd, 1)) return RETVAL_OBSOLETE_INPUT;
48 origPtr = get_bits(bd, 24);
49 - if ((int)origPtr > dbufSize) return RETVAL_DATA_ERROR;
50 + if (origPtr > bd->dbufSize) return RETVAL_DATA_ERROR;
52 /* mapping table: if some byte values are never used (encoding things
53 like ascii text), the compression code removes the gaps to have fewer
54 @@ -435,7 +435,14 @@ static int get_next_block(bunzip_data *bd)
55 symbols, but a run of length 0 doesn't mean anything in this
56 context). Thus space is saved. */
57 runCnt += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */
58 - if (runPos < dbufSize) runPos <<= 1;
59 +//The 32-bit overflow of runCnt wasn't yet seen, but probably can happen.
60 +//This would be the fix (catches too large count way before it can overflow):
61 +// if (runCnt > bd->dbufSize) {
62 +// dbg("runCnt:%u > dbufSize:%u RETVAL_DATA_ERROR",
63 +// runCnt, bd->dbufSize);
64 +// return RETVAL_DATA_ERROR;
66 + if (runPos < bd->dbufSize) runPos <<= 1;
67 goto end_of_huffman_loop;
70 @@ -445,14 +452,15 @@ static int get_next_block(bunzip_data *bd)
71 literal used is the one at the head of the mtfSymbol array.) */
74 - if (dbufCount + runCnt > dbufSize) {
75 - dbg("dbufCount:%d+runCnt:%d %d > dbufSize:%d RETVAL_DATA_ERROR",
76 - dbufCount, runCnt, dbufCount + runCnt, dbufSize);
77 + if (dbufCount + runCnt > bd->dbufSize) {
78 + dbg("dbufCount:%u+runCnt:%u %u > dbufSize:%u RETVAL_DATA_ERROR",
79 + dbufCount, runCnt, dbufCount + runCnt, bd->dbufSize);
80 return RETVAL_DATA_ERROR;
82 tmp_byte = symToByte[mtfSymbol[0]];
83 byteCount[tmp_byte] += runCnt;
84 - while (--runCnt >= 0) dbuf[dbufCount++] = (uint32_t)tmp_byte;
85 + while ((int)--runCnt >= 0)
86 + dbuf[dbufCount++] = (uint32_t)tmp_byte;
90 @@ -466,7 +474,7 @@ static int get_next_block(bunzip_data *bd)
91 first symbol in the mtf array, position 0, would have been handled
92 as part of a run above. Therefore 1 unused mtf position minus
93 2 non-literal nextSym values equals -1.) */
94 - if (dbufCount >= dbufSize) return RETVAL_DATA_ERROR;
95 + if (dbufCount >= bd->dbufSize) return RETVAL_DATA_ERROR;