File gunzip-fix-incorrect-decoding-of-fixed-inflate-blocks.patch of Package busybox.20467

From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Sat Oct 26 20:04:34 2019 +0200
Subject: gunzip: fix incorrect decoding of "fixed" inflate blocks
Patch-mainline: caf5ee0dd9250a4ca913691bcdc247f8fe814e22
Git-repo: https://git.busybox.net/busybox
Git-commit: 23496d2c904575b90ffcf0e67df1a30bb2171d30
References: 

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>
Signed-off-by: Egbert Eich <eich@suse.de>
---
 archival/libarchive/decompress_gunzip.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c
index 6571b23d7..4067e1170 100644
--- a/archival/libarchive/decompress_gunzip.c
+++ b/archival/libarchive/decompress_gunzip.c
@@ -281,11 +281,17 @@ static unsigned fill_bitbuffer(STATE_PARAM unsigned bitbuffer, unsigned *current
  * b:	code lengths in bits (all assumed <= BMAX)
  * n:	number of codes (assumed <= N_MAX)
  * s:	number of simple-valued codes (0..s-1)
- * d:	list of base values for non-simple codes
- * e:	list of extra bits for non-simple codes
+ * cp_ext->cp,ext: list of base values/extra bits for non-simple codes
  * m:	maximum lookup bits, returns actual
  * result: starting table
+ *
+ * On error, returns a value with lowest-bit set on error.
+ * It can be just the value of 0x1,
+ * or a valid pointer to a Huffman table, ORed with 0x1 if incompete table
+ * is given: "fixed inflate" decoder feeds us such data.
  */
+#define BAD_HUFT(p) ((uintptr_t)(p) & 1)
+#define ERR_RET     ((huft_t*)(uintptr_t)1)
 static huft_t* huft_build(const unsigned *b, const unsigned n,
 			const unsigned s, const struct cp_ext *cp_ext,
 			unsigned *m)
@@ -348,11 +354,11 @@ static huft_t* huft_build(const unsigned *b, const unsigned n,
 	for (y = 1 << j; j < i; j++, y <<= 1) {
 		y -= c[j];
 		if (y < 0)
-			return NULL; /* bad input: more codes than bits */
+			return ERR_RET; /* bad input: more codes than bits */
 	}
 	y -= c[i];
 	if (y < 0)
-		return NULL;
+		return ERR_RET;
 	c[i] += y;
 
 	/* Generate starting offsets into the value table for each length */
@@ -379,7 +385,7 @@ static huft_t* huft_build(const unsigned *b, const unsigned n,
 	} while (++i < n);
 
 	/* Generate the Huffman codes and for each, make the table entries */
-	result = NULL;
+	result = ERR_RET;
 	t = &result;
 	x[0] = i = 0;   /* first Huffman code is zero */
 	p = v;          /* grab values in bit order */
@@ -473,7 +479,8 @@ static huft_t* huft_build(const unsigned *b, const unsigned n,
 	*m = ws[1];
 
 	if (y != 0 && g != 1) /* we were given an incomplete table */
-		return NULL;
+		/* return "result" ORed with 1 */
+		return (void*)((uintptr_t)result | 1);
 
 	return result;
 }
@@ -777,13 +784,16 @@ static int inflate_block(STATE_PARAM smallint *e)
 			ll[i] = 8;
 		bl = 7;
 		inflate_codes_tl = huft_build(ll, 288, 257, &lit, &bl);
-		/* huft_build() never returns error here - we use known data */
+		/* ^^^ never returns error here - we use known data */
 
 		/* set up distance table */
 		for (i = 0; i < 30; i++) /* make an incomplete code set */
 			ll[i] = 5;
 		bd = 5;
 		inflate_codes_td = huft_build(ll, 30, 0, &dist, &bd);
+		/* ^^^ does return error here! (lsb bit is set) - we gave it incomplete code set */
+		/* clearing error bit: */
+		inflate_codes_td = (void*)((uintptr_t)inflate_codes_td & ~(uintptr_t)1);
 
 		/* set up data for inflate_codes() */
 		inflate_codes_setup(PASS_STATE bl, bd);
@@ -850,7 +860,7 @@ static int inflate_block(STATE_PARAM smallint *e)
 		/* build decoding table for trees - single level, 7 bit lookup */
 		bl = 7;
 		inflate_codes_tl = huft_build(ll, 19, 19, NULL, &bl);
-		if (!inflate_codes_tl) {
+		if (BAD_HUFT(inflate_codes_tl)) {
 			abort_unzip(PASS_STATE_ONLY);	/* incomplete code set */
 		}
 
@@ -915,12 +925,12 @@ static int inflate_block(STATE_PARAM smallint *e)
 		/* build the decoding tables for literal/length and distance codes */
 		bl = lbits;
 		inflate_codes_tl = huft_build(ll, nl, 257, &lit, &bl);
-		if (!inflate_codes_tl) {
+		if (BAD_HUFT(inflate_codes_tl)) {
 			abort_unzip(PASS_STATE_ONLY);
 		}
 		bd = dbits;
 		inflate_codes_td = huft_build(ll + nl, nd, 0, &dist, &bd);
-		if (!inflate_codes_td) {
+		if (BAD_HUFT(inflate_codes_td)) {
 			abort_unzip(PASS_STATE_ONLY);
 		}
 
openSUSE Build Service is sponsored by