diff options
author | Armin Kuster <akuster808@gmail.com> | 2016-02-13 11:55:53 -0800 |
---|---|---|
committer | Armin Kuster <akuster808@gmail.com> | 2016-02-21 07:49:40 -0800 |
commit | a715bdffac1fc70206a543a15a3528a8e69c85ad (patch) | |
tree | 022da524fd416cf51cd0bfa8962b147131b16c2d /meta-oe/recipes-support/xdelta | |
parent | dc5634968b270dde250690609f0015f881db81f2 (diff) | |
download | meta-openembedded-a715bdffac1fc70206a543a15a3528a8e69c85ad.tar.gz |
xdelta3: Security fix CVE-2014-9765
CVE-2014-9765 xdelta: buffer overflow in main_get_appheader
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Diffstat (limited to 'meta-oe/recipes-support/xdelta')
-rw-r--r-- | meta-oe/recipes-support/xdelta/files/CVE-2014-9765.patch | 311 | ||||
-rw-r--r-- | meta-oe/recipes-support/xdelta/xdelta3_3.0.8.bb | 1 |
2 files changed, 312 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/xdelta/files/CVE-2014-9765.patch b/meta-oe/recipes-support/xdelta/files/CVE-2014-9765.patch new file mode 100644 index 000000000..572a3c00a --- /dev/null +++ b/meta-oe/recipes-support/xdelta/files/CVE-2014-9765.patch | |||
@@ -0,0 +1,311 @@ | |||
1 | From ef93ff74203e030073b898c05e8b4860b5d09ef2 Mon Sep 17 00:00:00 2001 | ||
2 | From: "josh.macdonald" <jmacd@users.noreply.github.com> | ||
3 | Date: Sun, 12 Oct 2014 05:24:22 +0000 | ||
4 | Subject: [PATCH] Add appheader tests; fix buffer overflow in | ||
5 | main_get_appheader | ||
6 | |||
7 | Upstream-Status: Backport | ||
8 | |||
9 | This appears to be fixed in xdelta3 3.0.9 and later via | ||
10 | https://github.com/jmacd/xdelta-devel/commit/ef93ff74203e030073b898c05e8b4860b5d09ef2 | ||
11 | |||
12 | CVE: CVE-2014-9765 | ||
13 | Signed-off-by: Armin Kuster <akuster808@gmail.com> | ||
14 | |||
15 | --- | ||
16 | xdelta3-main.h | 5 +- | ||
17 | xdelta3-test.h | 131 +++++++++++++++++++++++++++++++++++++++---------- | ||
18 | 2 files changed, 108 insertions(+), 28 deletions(-) | ||
19 | |||
20 | diff --git a/xdelta3-main.h b/xdelta3-main.h | ||
21 | index 090b7d9..5146b38 100644 | ||
22 | --- a/xdelta3-main.h | ||
23 | +++ b/xdelta3-main.h | ||
24 | @@ -2810,14 +2810,15 @@ main_get_appheader (xd3_stream *stream, main_file *ifile, | ||
25 | |||
26 | if (appheadsz > 0) | ||
27 | { | ||
28 | + const int kMaxArgs = 4; | ||
29 | char *start = (char*)apphead; | ||
30 | char *slash; | ||
31 | int place = 0; | ||
32 | - char *parsed[4]; | ||
33 | + char *parsed[kMaxArgs]; | ||
34 | |||
35 | memset (parsed, 0, sizeof (parsed)); | ||
36 | |||
37 | - while ((slash = strchr (start, '/')) != NULL) | ||
38 | + while ((slash = strchr (start, '/')) != NULL && place < (kMaxArgs-1)) | ||
39 | { | ||
40 | *slash = 0; | ||
41 | parsed[place++] = start; | ||
42 | diff --git a/xdelta3-test.h b/xdelta3-test.h | ||
43 | index e9848b6..0e10251 100644 | ||
44 | --- a/xdelta3-test.h | ||
45 | +++ b/xdelta3-test.h | ||
46 | @@ -1,5 +1,5 @@ | ||
47 | /* xdelta 3 - delta compression tools and library Copyright (C) 2001, | ||
48 | - * 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012. | ||
49 | + * 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012. | ||
50 | * Joshua P. MacDonald | ||
51 | * | ||
52 | * This program is free software; you can redistribute it and/or modify | ||
53 | @@ -54,7 +54,7 @@ void mt_init(mtrand *mt, uint32_t seed) { | ||
54 | /* only MSBs of the array mt[]. */ | ||
55 | /* 2002/01/09 modified by Makoto Matsumoto */ | ||
56 | mt->mt_buffer_[i] = | ||
57 | - (1812433253UL * (mt->mt_buffer_[i-1] ^ | ||
58 | + (1812433253UL * (mt->mt_buffer_[i-1] ^ | ||
59 | (mt->mt_buffer_[i-1] >> 30)) + i); | ||
60 | } | ||
61 | } | ||
62 | @@ -69,20 +69,20 @@ uint32_t mt_random (mtrand *mt) { | ||
63 | int kk; | ||
64 | |||
65 | for (kk = 0; kk < MT_LEN - MT_IA; kk++) { | ||
66 | - y = (mt->mt_buffer_[kk] & UPPER_MASK) | | ||
67 | + y = (mt->mt_buffer_[kk] & UPPER_MASK) | | ||
68 | (mt->mt_buffer_[kk + 1] & LOWER_MASK); | ||
69 | - mt->mt_buffer_[kk] = mt->mt_buffer_[kk + MT_IA] ^ | ||
70 | + mt->mt_buffer_[kk] = mt->mt_buffer_[kk + MT_IA] ^ | ||
71 | (y >> 1) ^ mag01[y & 0x1UL]; | ||
72 | } | ||
73 | for (;kk < MT_LEN - 1; kk++) { | ||
74 | - y = (mt->mt_buffer_[kk] & UPPER_MASK) | | ||
75 | + y = (mt->mt_buffer_[kk] & UPPER_MASK) | | ||
76 | (mt->mt_buffer_[kk + 1] & LOWER_MASK); | ||
77 | - mt->mt_buffer_[kk] = mt->mt_buffer_[kk + (MT_IA - MT_LEN)] ^ | ||
78 | + mt->mt_buffer_[kk] = mt->mt_buffer_[kk + (MT_IA - MT_LEN)] ^ | ||
79 | (y >> 1) ^ mag01[y & 0x1UL]; | ||
80 | } | ||
81 | - y = (mt->mt_buffer_[MT_LEN - 1] & UPPER_MASK) | | ||
82 | + y = (mt->mt_buffer_[MT_LEN - 1] & UPPER_MASK) | | ||
83 | (mt->mt_buffer_[0] & LOWER_MASK); | ||
84 | - mt->mt_buffer_[MT_LEN - 1] = mt->mt_buffer_[MT_IA - 1] ^ | ||
85 | + mt->mt_buffer_[MT_LEN - 1] = mt->mt_buffer_[MT_IA - 1] ^ | ||
86 | (y >> 1) ^ mag01[y & 0x1UL]; | ||
87 | mt->mt_index_ = 0; | ||
88 | } | ||
89 | @@ -166,7 +166,7 @@ static int do_cmd (xd3_stream *stream, const char *buf) | ||
90 | { | ||
91 | stream->msg = "abnormal command termination"; | ||
92 | } | ||
93 | - return XD3_INTERNAL; | ||
94 | + return ret; | ||
95 | } | ||
96 | return 0; | ||
97 | } | ||
98 | @@ -257,8 +257,10 @@ int test_setup (void) | ||
99 | static int | ||
100 | test_make_inputs (xd3_stream *stream, xoff_t *ss_out, xoff_t *ts_out) | ||
101 | { | ||
102 | - usize_t ts = (mt_random (&static_mtrand) % TEST_FILE_MEAN) + TEST_FILE_MEAN / 2; | ||
103 | - usize_t ss = (mt_random (&static_mtrand) % TEST_FILE_MEAN) + TEST_FILE_MEAN / 2; | ||
104 | + usize_t ts = (mt_random (&static_mtrand) % TEST_FILE_MEAN) + | ||
105 | + TEST_FILE_MEAN / 2; | ||
106 | + usize_t ss = (mt_random (&static_mtrand) % TEST_FILE_MEAN) + | ||
107 | + TEST_FILE_MEAN / 2; | ||
108 | uint8_t *buf = (uint8_t*) malloc (ts + ss), *sbuf = buf, *tbuf = buf + ss; | ||
109 | usize_t sadd = 0, sadd_max = (usize_t)(ss * TEST_ADD_RATIO); | ||
110 | FILE *tf = NULL, *sf = NULL; | ||
111 | @@ -409,7 +411,7 @@ test_compare_files (const char* tgt, const char *rec) | ||
112 | { | ||
113 | if (obuf[i] != rbuf[i]) | ||
114 | { | ||
115 | - XPR(NT "byte %u (read %u @ %"Q"u) %d != %d\n", | ||
116 | + XPR(NT "byte %u (read %u @ %"Q"u) %d != %d\n", | ||
117 | (int)i, (int)oc, offset, obuf[i], rbuf[i]); | ||
118 | diffs++; | ||
119 | return XD3_INTERNAL; | ||
120 | @@ -421,7 +423,7 @@ test_compare_files (const char* tgt, const char *rec) | ||
121 | |||
122 | fclose (orig); | ||
123 | fclose (recons); | ||
124 | - if (diffs != 0) | ||
125 | + if (diffs != 0) | ||
126 | { | ||
127 | return XD3_INTERNAL; | ||
128 | } | ||
129 | @@ -429,12 +431,12 @@ test_compare_files (const char* tgt, const char *rec) | ||
130 | } | ||
131 | |||
132 | static int | ||
133 | -test_save_copy (const char *origname) | ||
134 | +test_copy_to (const char *from, const char *to) | ||
135 | { | ||
136 | char buf[TESTBUFSIZE]; | ||
137 | int ret; | ||
138 | |||
139 | - snprintf_func (buf, TESTBUFSIZE, "cp -f %s %s", origname, TEST_COPY_FILE); | ||
140 | + snprintf_func (buf, TESTBUFSIZE, "cp -f %s %s", from, to); | ||
141 | |||
142 | if ((ret = system (buf)) != 0) | ||
143 | { | ||
144 | @@ -445,6 +447,12 @@ test_save_copy (const char *origname) | ||
145 | } | ||
146 | |||
147 | static int | ||
148 | +test_save_copy (const char *origname) | ||
149 | +{ | ||
150 | + return test_copy_to(origname, TEST_COPY_FILE); | ||
151 | +} | ||
152 | + | ||
153 | +static int | ||
154 | test_file_size (const char* file, xoff_t *size) | ||
155 | { | ||
156 | struct stat sbuf; | ||
157 | @@ -499,7 +507,7 @@ test_read_integer_error (xd3_stream *stream, usize_t trunto, const char *msg) | ||
158 | inp = buf->base; | ||
159 | max = buf->base + buf->next - trunto; | ||
160 | |||
161 | - if ((ret = xd3_read_uint32_t (stream, & inp, max, & rval)) != | ||
162 | + if ((ret = xd3_read_uint32_t (stream, & inp, max, & rval)) != | ||
163 | XD3_INVALID_INPUT || | ||
164 | !MSG_IS (msg)) | ||
165 | { | ||
166 | @@ -1654,11 +1662,11 @@ test_compressed_stream_overflow (xd3_stream *stream, int ignore) | ||
167 | if ((buf = (uint8_t*) malloc (TWO_MEGS_AND_DELTA)) == NULL) { return ENOMEM; } | ||
168 | |||
169 | memset (buf, 0, TWO_MEGS_AND_DELTA); | ||
170 | - for (i = 0; i < (2 << 20); i += 256) | ||
171 | + for (i = 0; i < (2 << 20); i += 256) | ||
172 | { | ||
173 | int j; | ||
174 | int off = mt_random(& static_mtrand) % 10; | ||
175 | - for (j = 0; j < 256; j++) | ||
176 | + for (j = 0; j < 256; j++) | ||
177 | { | ||
178 | buf[i + j] = j + off; | ||
179 | } | ||
180 | @@ -1683,11 +1691,11 @@ test_compressed_stream_overflow (xd3_stream *stream, int ignore) | ||
181 | } | ||
182 | |||
183 | /* Test transfer of exactly 32bits worth of data. */ | ||
184 | - if ((ret = test_streaming (stream, | ||
185 | - buf, | ||
186 | - buf + (1 << 20), | ||
187 | - buf + (2 << 20), | ||
188 | - 1 << 12))) | ||
189 | + if ((ret = test_streaming (stream, | ||
190 | + buf, | ||
191 | + buf + (1 << 20), | ||
192 | + buf + (2 << 20), | ||
193 | + 1 << 12))) | ||
194 | { | ||
195 | goto fail; | ||
196 | } | ||
197 | @@ -1889,7 +1897,7 @@ test_recode_command2 (xd3_stream *stream, int has_source, | ||
198 | } | ||
199 | |||
200 | /* First encode */ | ||
201 | - snprintf_func (ecmd, TESTBUFSIZE, "%s %s -f %s %s %s %s %s %s %s", | ||
202 | + snprintf_func (ecmd, TESTBUFSIZE, "%s %s -f %s %s %s %s %s %s %s", | ||
203 | program_name, test_softcfg_str, | ||
204 | has_adler32 ? "" : "-n ", | ||
205 | has_apphead ? "-A=encode_apphead " : "-A= ", | ||
206 | @@ -1910,7 +1918,7 @@ test_recode_command2 (xd3_stream *stream, int has_source, | ||
207 | snprintf_func (recmd, TESTBUFSIZE, | ||
208 | "%s recode %s -f %s %s %s %s %s", program_name, test_softcfg_str, | ||
209 | recoded_adler32 ? "" : "-n ", | ||
210 | - !change_apphead ? "" : | ||
211 | + !change_apphead ? "" : | ||
212 | (recoded_apphead ? "-A=recode_apphead " : "-A= "), | ||
213 | recoded_secondary ? "-S djw " : "-S none ", | ||
214 | TEST_DELTA_FILE, | ||
215 | @@ -2361,6 +2369,76 @@ test_no_output (xd3_stream *stream, int ignore) | ||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | +/* This tests that the default appheader works */ | ||
220 | +static int | ||
221 | +test_appheader (xd3_stream *stream, int ignore) | ||
222 | +{ | ||
223 | + int i; | ||
224 | + int ret; | ||
225 | + char buf[TESTBUFSIZE]; | ||
226 | + char bogus[TESTBUFSIZE]; | ||
227 | + xoff_t ssize, tsize; | ||
228 | + test_setup (); | ||
229 | + | ||
230 | + if ((ret = test_make_inputs (stream, &ssize, &tsize))) { return ret; } | ||
231 | + | ||
232 | + snprintf_func (buf, TESTBUFSIZE, "%s -q -f -e -s %s %s %s", program_name, | ||
233 | + TEST_SOURCE_FILE, TEST_TARGET_FILE, TEST_DELTA_FILE); | ||
234 | + if ((ret = do_cmd (stream, buf))) { return ret; } | ||
235 | + | ||
236 | + if ((ret = test_copy_to (program_name, TEST_RECON2_FILE))) { return ret; } | ||
237 | + | ||
238 | + snprintf_func (buf, TESTBUFSIZE, "chmod 0700 %s", TEST_RECON2_FILE); | ||
239 | + if ((ret = do_cmd (stream, buf))) { return ret; } | ||
240 | + | ||
241 | + if ((ret = test_save_copy (TEST_TARGET_FILE))) { return ret; } | ||
242 | + if ((ret = test_copy_to (TEST_SOURCE_FILE, TEST_TARGET_FILE))) { return ret; } | ||
243 | + | ||
244 | + if ((ret = test_compare_files (TEST_TARGET_FILE, TEST_COPY_FILE)) == 0) | ||
245 | + { | ||
246 | + return XD3_INVALID; // I.e., files are different! | ||
247 | + } | ||
248 | + | ||
249 | + // Test that the target file is restored. | ||
250 | + snprintf_func (buf, TESTBUFSIZE, "(cd /tmp && %s -q -f -d %s)", | ||
251 | + TEST_RECON2_FILE, | ||
252 | + TEST_DELTA_FILE); | ||
253 | + if ((ret = do_cmd (stream, buf))) { return ret; } | ||
254 | + | ||
255 | + if ((ret = test_compare_files (TEST_TARGET_FILE, TEST_COPY_FILE)) != 0) | ||
256 | + { | ||
257 | + return ret; | ||
258 | + } | ||
259 | + | ||
260 | + // Test a malicious string w/ entries > 4 in the appheader by having | ||
261 | + // the encoder write it: | ||
262 | + for (i = 0; i < TESTBUFSIZE / 4; ++i) | ||
263 | + { | ||
264 | + bogus[2*i] = 'G'; | ||
265 | + bogus[2*i+1] = '/'; | ||
266 | + } | ||
267 | + bogus[TESTBUFSIZE/2-1] = 0; | ||
268 | + | ||
269 | + snprintf_func (buf, TESTBUFSIZE, | ||
270 | + "%s -q -f -A=%s -e -s %s %s %s", program_name, bogus, | ||
271 | + TEST_SOURCE_FILE, TEST_TARGET_FILE, TEST_DELTA_FILE); | ||
272 | + if ((ret = do_cmd (stream, buf))) { return ret; } | ||
273 | + // Then read it: | ||
274 | + snprintf_func (buf, TESTBUFSIZE, "(cd /tmp && %s -q -f -d %s)", | ||
275 | + TEST_RECON2_FILE, | ||
276 | + TEST_DELTA_FILE); | ||
277 | + if ((ret = do_cmd (stream, buf)) == 0) | ||
278 | + { | ||
279 | + return XD3_INVALID; // Impossible | ||
280 | + } | ||
281 | + if (!WIFEXITED(ret)) | ||
282 | + { | ||
283 | + return XD3_INVALID; // Must have crashed! | ||
284 | + } | ||
285 | + | ||
286 | + return 0; | ||
287 | +} | ||
288 | + | ||
289 | /*********************************************************************** | ||
290 | Source identical optimization | ||
291 | ***********************************************************************/ | ||
292 | @@ -2603,7 +2681,7 @@ test_string_matching (xd3_stream *stream, int ignore) | ||
293 | default: CHECK(0); | ||
294 | } | ||
295 | |||
296 | - snprintf_func (rptr, rbuf+TESTBUFSIZE-rptr, "%d/%d", | ||
297 | + snprintf_func (rptr, rbuf+TESTBUFSIZE-rptr, "%d/%d", | ||
298 | inst->pos, inst->size); | ||
299 | rptr += strlen (rptr); | ||
300 | |||
301 | @@ -2848,6 +2926,7 @@ xd3_selftest (void) | ||
302 | DO_TEST (force_behavior, 0, 0); | ||
303 | DO_TEST (stdout_behavior, 0, 0); | ||
304 | DO_TEST (no_output, 0, 0); | ||
305 | + DO_TEST (appheader, 0, 0); | ||
306 | DO_TEST (command_line_arguments, 0, 0); | ||
307 | |||
308 | #if EXTERNAL_COMPRESSION | ||
309 | -- | ||
310 | 2.3.5 | ||
311 | |||
diff --git a/meta-oe/recipes-support/xdelta/xdelta3_3.0.8.bb b/meta-oe/recipes-support/xdelta/xdelta3_3.0.8.bb index baa92e4bb..2ddf78a0f 100644 --- a/meta-oe/recipes-support/xdelta/xdelta3_3.0.8.bb +++ b/meta-oe/recipes-support/xdelta/xdelta3_3.0.8.bb | |||
@@ -10,6 +10,7 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=393a5ca445f6965873eca0259a17f833" | |||
10 | SRC_URI = "http://xdelta.googlecode.com/files/${BPN}-${PV}.tar.xz \ | 10 | SRC_URI = "http://xdelta.googlecode.com/files/${BPN}-${PV}.tar.xz \ |
11 | file://compilation-fix.patch \ | 11 | file://compilation-fix.patch \ |
12 | file://with-liblzma-configure-option.patch \ | 12 | file://with-liblzma-configure-option.patch \ |
13 | file://CVE-2014-9765.patch \ | ||
13 | " | 14 | " |
14 | SRC_URI[md5sum] = "c3ae3286ce4193de8e03d5bcaccf3bc3" | 15 | SRC_URI[md5sum] = "c3ae3286ce4193de8e03d5bcaccf3bc3" |
15 | SRC_URI[sha256sum] = "3a86f29c95664fb44b8a40ff22d9bcc3e87aa8c01f0ff75931a7fa78ed3d2e55" | 16 | SRC_URI[sha256sum] = "3a86f29c95664fb44b8a40ff22d9bcc3e87aa8c01f0ff75931a7fa78ed3d2e55" |