aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/busybox/busybox/busybox-1.24.1-unzip-regression.patch
blob: e3c502091f0cb8d5ca9f9717649b80b00aae8bc1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
Upstream-Status: Backport

  http://busybox.net/downloads/fixes-1.24.1/
  http://git.busybox.net/busybox/commit/?id=092fabcf1df5d46cd22be4ffcd3b871f6180eb9c
  http://git.busybox.net/busybox/commit/?h=1_24_stable&id=092fabcf1df5d46cd22be4ffcd3b871f6180eb9c

Signed-off-by: Andre McCurdy <armccurdy@gmail.com>

From 092fabcf1df5d46cd22be4ffcd3b871f6180eb9c Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Fri, 30 Oct 2015 23:41:53 +0100
Subject: [PATCH] [g]unzip: fix recent breakage.

Also, do emit error message we so painstakingly pass from gzip internals

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
(cherry picked from commit 6bd3fff51aa74e2ee2d87887b12182a3b09792ef)
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 archival/libarchive/decompress_gunzip.c | 33 +++++++++++++++++++++------------
 testsuite/unzip.tests                   |  1 +
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c
index c76fd31..357c9bf 100644
--- a/archival/libarchive/decompress_gunzip.c
+++ b/archival/libarchive/decompress_gunzip.c
@@ -309,8 +309,7 @@ static int huft_build(const unsigned *b, const unsigned n,
 	huft_t *q;              /* points to current table */
 	huft_t r;               /* table entry for structure assignment */
 	huft_t *u[BMAX];        /* table stack */
-	unsigned v[N_MAX];      /* values in order of bit length */
-	unsigned v_end;
+	unsigned v[N_MAX + 1];  /* values in order of bit length. last v[] is never used */
 	int ws[BMAX + 1];       /* bits decoded stack */
 	int w;                  /* bits decoded */
 	unsigned x[BMAX + 1];   /* bit offsets, then code stack */
@@ -365,15 +364,17 @@ static int huft_build(const unsigned *b, const unsigned n,
 		*xp++ = j;
 	}
 
-	/* Make a table of values in order of bit lengths */
+	/* Make a table of values in order of bit lengths.
+	 * To detect bad input, unused v[i]'s are set to invalid value UINT_MAX.
+	 * In particular, last v[i] is never filled and must not be accessed.
+	 */
+	memset(v, 0xff, sizeof(v));
 	p = b;
 	i = 0;
-	v_end = 0;
 	do {
 		j = *p++;
 		if (j != 0) {
 			v[x[j]++] = i;
-			v_end = x[j];
 		}
 	} while (++i < n);
 
@@ -435,7 +436,9 @@ static int huft_build(const unsigned *b, const unsigned n,
 
 			/* set up table entry in r */
 			r.b = (unsigned char) (k - w);
-			if (p >= v + v_end) { // Was "if (p >= v + n)" but v[] can be shorter!
+			if (/*p >= v + n || -- redundant, caught by the second check: */
+			    *p == UINT_MAX /* do we access uninited v[i]? (see memset(v))*/
+			) {
 				r.e = 99; /* out of values--invalid code */
 			} else if (*p < s) {
 				r.e = (unsigned char) (*p < 256 ? 16 : 15);	/* 256 is EOB code */
@@ -520,8 +523,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY)
 		e = t->e;
 		if (e > 16)
 			do {
-				if (e == 99)
-					abort_unzip(PASS_STATE_ONLY);;
+				if (e == 99) {
+					abort_unzip(PASS_STATE_ONLY);
+				}
 				bb >>= t->b;
 				k -= t->b;
 				e -= 16;
@@ -557,8 +561,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY)
 			e = t->e;
 			if (e > 16)
 				do {
-					if (e == 99)
+					if (e == 99) {
 						abort_unzip(PASS_STATE_ONLY);
+					}
 					bb >>= t->b;
 					k -= t->b;
 					e -= 16;
@@ -824,8 +829,9 @@ static int inflate_block(STATE_PARAM smallint *e)
 
 		b_dynamic >>= 4;
 		k_dynamic -= 4;
-		if (nl > 286 || nd > 30)
+		if (nl > 286 || nd > 30) {
 			abort_unzip(PASS_STATE_ONLY);	/* bad lengths */
+		}
 
 		/* read in bit-length-code lengths */
 		for (j = 0; j < nb; j++) {
@@ -906,12 +912,14 @@ static int inflate_block(STATE_PARAM smallint *e)
 		bl = lbits;
 
 		i = huft_build(ll, nl, 257, cplens, cplext, &inflate_codes_tl, &bl);
-		if (i != 0)
+		if (i != 0) {
 			abort_unzip(PASS_STATE_ONLY);
+		}
 		bd = dbits;
 		i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &inflate_codes_td, &bd);
-		if (i != 0)
+		if (i != 0) {
 			abort_unzip(PASS_STATE_ONLY);
+		}
 
 		/* set up data for inflate_codes() */
 		inflate_codes_setup(PASS_STATE bl, bd);
@@ -999,6 +1007,7 @@ inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate)
 	error_msg = "corrupted data";
 	if (setjmp(error_jmp)) {
 		/* Error from deep inside zip machinery */
+		bb_error_msg(error_msg);
 		n = -1;
 		goto ret;
 	}
diff --git a/testsuite/unzip.tests b/testsuite/unzip.tests
index ca0a458..d8738a3 100755
--- a/testsuite/unzip.tests
+++ b/testsuite/unzip.tests
@@ -34,6 +34,7 @@ rm foo.zip
 testing "unzip (bad archive)" "uudecode; unzip bad.zip 2>&1; echo \$?" \
 "Archive:  bad.zip
   inflating: ]3j½r«IK-%Ix
+unzip: corrupted data
 unzip: inflate error
 1
 " \
-- 
2.6.2