diff options
-rw-r--r-- | meta/recipes-extended/tar/tar/CVE-2018-20482.patch | 405 | ||||
-rw-r--r-- | meta/recipes-extended/tar/tar_1.30.bb | 1 |
2 files changed, 406 insertions, 0 deletions
diff --git a/meta/recipes-extended/tar/tar/CVE-2018-20482.patch b/meta/recipes-extended/tar/tar/CVE-2018-20482.patch new file mode 100644 index 0000000000..2a13148427 --- /dev/null +++ b/meta/recipes-extended/tar/tar/CVE-2018-20482.patch | |||
@@ -0,0 +1,405 @@ | |||
1 | From 331be56598b284d41370c67046df25673b040a55 Mon Sep 17 00:00:00 2001 | ||
2 | From: Sergey Poznyakoff <gray@gnu.org> | ||
3 | Date: Thu, 27 Dec 2018 17:48:57 +0200 | ||
4 | Subject: [PATCH] Fix CVE-2018-20482 | ||
5 | |||
6 | * NEWS: Update. | ||
7 | * src/sparse.c (sparse_dump_region): Handle short read condition. | ||
8 | (sparse_extract_region,check_data_region): Fix dumped_size calculation. | ||
9 | Handle short read condition. | ||
10 | (pax_decode_header): Fix dumped_size calculation. | ||
11 | * tests/Makefile.am: Add new testcases. | ||
12 | * tests/testsuite.at: Likewise. | ||
13 | |||
14 | * tests/sptrcreat.at: New file. | ||
15 | * tests/sptrdiff00.at: New file. | ||
16 | * tests/sptrdiff01.at: New file. | ||
17 | |||
18 | CVE: CVE-2018-20482 | ||
19 | Upstream-Status: Backport | ||
20 | [http://git.savannah.gnu.org/cgit/tar.git/commit/?id=c15c42ccd1e2377945fd0414eca1a49294bff454] | ||
21 | |||
22 | Signed-off-by: Dan Tran <dantran@microsoft.com> | ||
23 | --- | ||
24 | src/sparse.c | 50 +++++++++++++++++++++++++++++++----- | ||
25 | tests/Makefile.am | 5 +++- | ||
26 | tests/sptrcreat.at | 62 +++++++++++++++++++++++++++++++++++++++++++++ | ||
27 | tests/sptrdiff00.at | 55 ++++++++++++++++++++++++++++++++++++++++ | ||
28 | tests/sptrdiff01.at | 55 ++++++++++++++++++++++++++++++++++++++++ | ||
29 | tests/testsuite.at | 5 +++- | ||
30 | 6 files changed, 224 insertions(+), 8 deletions(-) | ||
31 | create mode 100644 tests/sptrcreat.at | ||
32 | create mode 100644 tests/sptrdiff00.at | ||
33 | create mode 100644 tests/sptrdiff01.at | ||
34 | |||
35 | diff --git a/src/sparse.c b/src/sparse.c | ||
36 | index 0830f62..e8e8259 100644 | ||
37 | --- a/src/sparse.c | ||
38 | +++ b/src/sparse.c | ||
39 | @@ -1,6 +1,6 @@ | ||
40 | /* Functions for dealing with sparse files | ||
41 | |||
42 | - Copyright 2003-2007, 2010, 2013-2017 Free Software Foundation, Inc. | ||
43 | + Copyright 2003-2007, 2010, 2013-2018 Free Software Foundation, Inc. | ||
44 | |||
45 | This program is free software; you can redistribute it and/or modify it | ||
46 | under the terms of the GNU General Public License as published by the | ||
47 | @@ -427,6 +427,30 @@ sparse_dump_region (struct tar_sparse_file *file, size_t i) | ||
48 | bufsize); | ||
49 | return false; | ||
50 | } | ||
51 | + else if (bytes_read == 0) | ||
52 | + { | ||
53 | + char buf[UINTMAX_STRSIZE_BOUND]; | ||
54 | + struct stat st; | ||
55 | + size_t n; | ||
56 | + if (fstat (file->fd, &st) == 0) | ||
57 | + n = file->stat_info->stat.st_size - st.st_size; | ||
58 | + else | ||
59 | + n = file->stat_info->stat.st_size | ||
60 | + - (file->stat_info->sparse_map[i].offset | ||
61 | + + file->stat_info->sparse_map[i].numbytes | ||
62 | + - bytes_left); | ||
63 | + | ||
64 | + WARNOPT (WARN_FILE_SHRANK, | ||
65 | + (0, 0, | ||
66 | + ngettext ("%s: File shrank by %s byte; padding with zeros", | ||
67 | + "%s: File shrank by %s bytes; padding with zeros", | ||
68 | + n), | ||
69 | + quotearg_colon (file->stat_info->orig_file_name), | ||
70 | + STRINGIFY_BIGINT (n, buf))); | ||
71 | + if (! ignore_failed_read_option) | ||
72 | + set_exit_status (TAREXIT_DIFFERS); | ||
73 | + return false; | ||
74 | + } | ||
75 | |||
76 | memset (blk->buffer + bytes_read, 0, BLOCKSIZE - bytes_read); | ||
77 | bytes_left -= bytes_read; | ||
78 | @@ -464,9 +488,9 @@ sparse_extract_region (struct tar_sparse_file *file, size_t i) | ||
79 | return false; | ||
80 | } | ||
81 | set_next_block_after (blk); | ||
82 | + file->dumped_size += BLOCKSIZE; | ||
83 | count = blocking_write (file->fd, blk->buffer, wrbytes); | ||
84 | write_size -= count; | ||
85 | - file->dumped_size += count; | ||
86 | mv_size_left (file->stat_info->archive_file_size - file->dumped_size); | ||
87 | file->offset += count; | ||
88 | if (count != wrbytes) | ||
89 | @@ -598,6 +622,12 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end) | ||
90 | rdsize); | ||
91 | return false; | ||
92 | } | ||
93 | + else if (bytes_read == 0) | ||
94 | + { | ||
95 | + report_difference (file->stat_info, _("Size differs")); | ||
96 | + return false; | ||
97 | + } | ||
98 | + | ||
99 | if (!zero_block_p (diff_buffer, bytes_read)) | ||
100 | { | ||
101 | char begbuf[INT_BUFSIZE_BOUND (off_t)]; | ||
102 | @@ -609,6 +639,7 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end) | ||
103 | |||
104 | beg += bytes_read; | ||
105 | } | ||
106 | + | ||
107 | return true; | ||
108 | } | ||
109 | |||
110 | @@ -635,6 +666,7 @@ check_data_region (struct tar_sparse_file *file, size_t i) | ||
111 | return false; | ||
112 | } | ||
113 | set_next_block_after (blk); | ||
114 | + file->dumped_size += BLOCKSIZE; | ||
115 | bytes_read = safe_read (file->fd, diff_buffer, rdsize); | ||
116 | if (bytes_read == SAFE_READ_ERROR) | ||
117 | { | ||
118 | @@ -645,7 +677,11 @@ check_data_region (struct tar_sparse_file *file, size_t i) | ||
119 | rdsize); | ||
120 | return false; | ||
121 | } | ||
122 | - file->dumped_size += bytes_read; | ||
123 | + else if (bytes_read == 0) | ||
124 | + { | ||
125 | + report_difference (¤t_stat_info, _("Size differs")); | ||
126 | + return false; | ||
127 | + } | ||
128 | size_left -= bytes_read; | ||
129 | mv_size_left (file->stat_info->archive_file_size - file->dumped_size); | ||
130 | if (memcmp (blk->buffer, diff_buffer, rdsize)) | ||
131 | @@ -1213,7 +1249,8 @@ pax_decode_header (struct tar_sparse_file *file) | ||
132 | union block *blk; | ||
133 | char *p; | ||
134 | size_t i; | ||
135 | - | ||
136 | + off_t start; | ||
137 | + | ||
138 | #define COPY_BUF(b,buf,src) do \ | ||
139 | { \ | ||
140 | char *endp = b->buffer + BLOCKSIZE; \ | ||
141 | @@ -1229,7 +1266,6 @@ pax_decode_header (struct tar_sparse_file *file) | ||
142 | if (src == endp) \ | ||
143 | { \ | ||
144 | set_next_block_after (b); \ | ||
145 | - file->dumped_size += BLOCKSIZE; \ | ||
146 | b = find_next_block (); \ | ||
147 | if (!b) \ | ||
148 | FATAL_ERROR ((0, 0, _("Unexpected EOF in archive"))); \ | ||
149 | @@ -1242,8 +1278,8 @@ pax_decode_header (struct tar_sparse_file *file) | ||
150 | dst[-1] = 0; \ | ||
151 | } while (0) | ||
152 | |||
153 | + start = current_block_ordinal (); | ||
154 | set_next_block_after (current_header); | ||
155 | - file->dumped_size += BLOCKSIZE; | ||
156 | blk = find_next_block (); | ||
157 | if (!blk) | ||
158 | FATAL_ERROR ((0, 0, _("Unexpected EOF in archive"))); | ||
159 | @@ -1282,6 +1318,8 @@ pax_decode_header (struct tar_sparse_file *file) | ||
160 | sparse_add_map (file->stat_info, &sp); | ||
161 | } | ||
162 | set_next_block_after (blk); | ||
163 | + | ||
164 | + file->dumped_size += BLOCKSIZE * (current_block_ordinal () - start); | ||
165 | } | ||
166 | |||
167 | return true; | ||
168 | diff --git a/tests/Makefile.am b/tests/Makefile.am | ||
169 | index 2d7939d..ac3b6e7 100644 | ||
170 | --- a/tests/Makefile.am | ||
171 | +++ b/tests/Makefile.am | ||
172 | @@ -1,6 +1,6 @@ | ||
173 | # Makefile for GNU tar regression tests. | ||
174 | |||
175 | -# Copyright 1996-1997, 1999-2001, 2003-2007, 2009, 2012-2015 Free Software | ||
176 | +# Copyright 1996-1997, 1999-2001, 2003-2007, 2009, 2012-2018 Free Software | ||
177 | |||
178 | # This file is part of GNU tar. | ||
179 | |||
180 | @@ -228,6 +228,9 @@ TESTSUITE_AT = \ | ||
181 | spmvp00.at\ | ||
182 | spmvp01.at\ | ||
183 | spmvp10.at\ | ||
184 | + sptrcreat.at\ | ||
185 | + sptrdiff00.at\ | ||
186 | + sptrdiff01.at\ | ||
187 | time01.at\ | ||
188 | time02.at\ | ||
189 | truncate.at\ | ||
190 | diff --git a/tests/sptrcreat.at b/tests/sptrcreat.at | ||
191 | new file mode 100644 | ||
192 | index 0000000..8e28f0e | ||
193 | --- /dev/null | ||
194 | +++ b/tests/sptrcreat.at | ||
195 | @@ -0,0 +1,62 @@ | ||
196 | +# Process this file with autom4te to create testsuite. -*- Autotest -*- | ||
197 | + | ||
198 | +# Test suite for GNU tar. | ||
199 | +# Copyright 2018 Free Software Foundation, Inc. | ||
200 | + | ||
201 | +# This file is part of GNU tar. | ||
202 | + | ||
203 | +# GNU tar is free software; you can redistribute it and/or modify | ||
204 | +# it under the terms of the GNU General Public License as published by | ||
205 | +# the Free Software Foundation; either version 3 of the License, or | ||
206 | +# (at your option) any later version. | ||
207 | + | ||
208 | +# GNU tar is distributed in the hope that it will be useful, | ||
209 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
210 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
211 | +# GNU General Public License for more details. | ||
212 | + | ||
213 | +# You should have received a copy of the GNU General Public License | ||
214 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
215 | + | ||
216 | +# Tar up to 1.30 would loop endlessly if a sparse file had been truncated | ||
217 | +# while being archived (with --sparse flag). | ||
218 | +# | ||
219 | +# The bug has been assigned id CVE-2018-20482 (on the grounds that it is a | ||
220 | +# denial of service possibility). | ||
221 | +# | ||
222 | +# Reported by: Chris Siebenmann <cks.gnutar-01@cs.toronto.edu> | ||
223 | +# References: <20181226223948.781EB32008E@apps1.cs.toronto.edu>, | ||
224 | +# <http://lists.gnu.org/archive/html/bug-tar/2018-12/msg00023.html> | ||
225 | +# <https://utcc.utoronto.ca/~cks/space/blog/sysadmin/TarFindingTruncateBug> | ||
226 | +# <https://nvd.nist.gov/vuln/detail/CVE-2018-20482> | ||
227 | + | ||
228 | +AT_SETUP([sparse file truncated while archiving]) | ||
229 | +AT_KEYWORDS([truncate filechange sparse sptr sptrcreat]) | ||
230 | + | ||
231 | +AT_TAR_CHECK([ | ||
232 | +genfile --sparse --block-size=1024 --file foo \ | ||
233 | + 0 ABCDEFGHIJ 1M ABCDEFGHIJ 10M ABCDEFGHIJ 200M ABCDEFGHIJ | ||
234 | +genfile --file baz | ||
235 | +genfile --run --checkpoint 3 --length 200m --truncate foo -- \ | ||
236 | + tar --checkpoint=1 \ | ||
237 | + --checkpoint-action=echo \ | ||
238 | + --checkpoint-action=sleep=1 \ | ||
239 | + --sparse -vcf bar foo baz | ||
240 | +echo Exit status: $? | ||
241 | +echo separator | ||
242 | +genfile --file foo --seek 200m --length 11575296 --pattern=zeros | ||
243 | +tar dvf bar], | ||
244 | +[1], | ||
245 | +[foo | ||
246 | +baz | ||
247 | +Exit status: 1 | ||
248 | +separator | ||
249 | +foo | ||
250 | +foo: Mod time differs | ||
251 | +baz | ||
252 | +], | ||
253 | +[tar: foo: File shrank by 11575296 bytes; padding with zeros | ||
254 | +], | ||
255 | +[],[],[posix, gnu, oldgnu]) | ||
256 | + | ||
257 | +AT_CLEANUP | ||
258 | diff --git a/tests/sptrdiff00.at b/tests/sptrdiff00.at | ||
259 | new file mode 100644 | ||
260 | index 0000000..c410561 | ||
261 | --- /dev/null | ||
262 | +++ b/tests/sptrdiff00.at | ||
263 | @@ -0,0 +1,55 @@ | ||
264 | +# Process this file with autom4te to create testsuite. -*- Autotest -*- | ||
265 | +# | ||
266 | +# Test suite for GNU tar. | ||
267 | +# Copyright 2018 Free Software Foundation, Inc. | ||
268 | +# | ||
269 | +# This file is part of GNU tar. | ||
270 | +# | ||
271 | +# GNU tar is free software; you can redistribute it and/or modify | ||
272 | +# it under the terms of the GNU General Public License as published by | ||
273 | +# the Free Software Foundation; either version 3 of the License, or | ||
274 | +# (at your option) any later version. | ||
275 | +# | ||
276 | +# GNU tar is distributed in the hope that it will be useful, | ||
277 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
278 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
279 | +# GNU General Public License for more details. | ||
280 | +# | ||
281 | +# You should have received a copy of the GNU General Public License | ||
282 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
283 | + | ||
284 | +# While fixing CVE-2018-20482 (see sptrcreat.at) it has been discovered | ||
285 | +# that similar bug exists in file checking code (tar d). | ||
286 | +# This test case checks if tar correctly handles a short read condition | ||
287 | +# appearing in check_sparse_region. | ||
288 | + | ||
289 | +AT_SETUP([file truncated in sparse region while comparing]) | ||
290 | +AT_KEYWORDS([truncate filechange sparse sptr sptrdiff diff]) | ||
291 | + | ||
292 | +# This triggers short read in check_sparse_region. | ||
293 | +AT_TAR_CHECK([ | ||
294 | +genfile --sparse --block-size=1024 --file foo \ | ||
295 | + 0 ABCDEFGHIJ 1M ABCDEFGHIJ 10M ABCDEFGHIJ 200M ABCDEFGHIJ | ||
296 | +genfile --file baz | ||
297 | +echo creating | ||
298 | +tar --sparse -vcf bar foo baz | ||
299 | +echo comparing | ||
300 | +genfile --run --checkpoint 3 --length 200m --truncate foo -- \ | ||
301 | + tar --checkpoint=1 \ | ||
302 | + --checkpoint-action=echo='Write checkpoint %u' \ | ||
303 | + --checkpoint-action=sleep=1 \ | ||
304 | + --sparse -vdf bar | ||
305 | +], | ||
306 | +[1], | ||
307 | +[creating | ||
308 | +foo | ||
309 | +baz | ||
310 | +comparing | ||
311 | +foo | ||
312 | +foo: Size differs | ||
313 | +baz | ||
314 | +], | ||
315 | +[], | ||
316 | +[],[],[posix, gnu, oldgnu]) | ||
317 | + | ||
318 | +AT_CLEANUP | ||
319 | diff --git a/tests/sptrdiff01.at b/tests/sptrdiff01.at | ||
320 | new file mode 100644 | ||
321 | index 0000000..2da2267 | ||
322 | --- /dev/null | ||
323 | +++ b/tests/sptrdiff01.at | ||
324 | @@ -0,0 +1,55 @@ | ||
325 | +# Process this file with autom4te to create testsuite. -*- Autotest -*- | ||
326 | +# | ||
327 | +# Test suite for GNU tar. | ||
328 | +# Copyright 2018 Free Software Foundation, Inc. | ||
329 | +# | ||
330 | +# This file is part of GNU tar. | ||
331 | +# | ||
332 | +# GNU tar is free software; you can redistribute it and/or modify | ||
333 | +# it under the terms of the GNU General Public License as published by | ||
334 | +# the Free Software Foundation; either version 3 of the License, or | ||
335 | +# (at your option) any later version. | ||
336 | +# | ||
337 | +# GNU tar is distributed in the hope that it will be useful, | ||
338 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
339 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
340 | +# GNU General Public License for more details. | ||
341 | +# | ||
342 | +# You should have received a copy of the GNU General Public License | ||
343 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
344 | + | ||
345 | +# While fixing CVE-2018-20482 (see sptrcreat.at) it has been discovered | ||
346 | +# that similar bug exists in file checking code (tar d). | ||
347 | +# This test case checks if tar correctly handles a short read condition | ||
348 | +# appearing in check_data_region. | ||
349 | + | ||
350 | +AT_SETUP([file truncated in data region while comparing]) | ||
351 | +AT_KEYWORDS([truncate filechange sparse sptr sptrdiff diff]) | ||
352 | + | ||
353 | +# This triggers short read in check_data_region. | ||
354 | +AT_TAR_CHECK([ | ||
355 | +genfile --sparse --block-size=1024 --file foo \ | ||
356 | + 0 ABCDEFGHIJ 1M ABCDEFGHIJ 10M ABCDEFGHIJ 200M ABCDEFGHIJ | ||
357 | +genfile --file baz | ||
358 | +echo creating | ||
359 | +tar --sparse -vcf bar foo baz | ||
360 | +echo comparing | ||
361 | +genfile --run --checkpoint 5 --length 221278210 --truncate foo -- \ | ||
362 | + tar --checkpoint=1 \ | ||
363 | + --checkpoint-action=echo='Write checkpoint %u' \ | ||
364 | + --checkpoint-action=sleep=1 \ | ||
365 | + --sparse -vdf bar | ||
366 | +], | ||
367 | +[1], | ||
368 | +[creating | ||
369 | +foo | ||
370 | +baz | ||
371 | +comparing | ||
372 | +foo | ||
373 | +foo: Size differs | ||
374 | +baz | ||
375 | +], | ||
376 | +[], | ||
377 | +[],[],[posix, gnu, oldgnu]) | ||
378 | + | ||
379 | +AT_CLEANUP | ||
380 | diff --git a/tests/testsuite.at b/tests/testsuite.at | ||
381 | index 2a83757..23386f7 100644 | ||
382 | --- a/tests/testsuite.at | ||
383 | +++ b/tests/testsuite.at | ||
384 | @@ -1,7 +1,7 @@ | ||
385 | # Process this file with autom4te to create testsuite. -*- Autotest -*- | ||
386 | |||
387 | # Test suite for GNU tar. | ||
388 | -# Copyright 2004-2008, 2010-2017 Free Software Foundation, Inc. | ||
389 | +# Copyright 2004-2008, 2010-2018 Free Software Foundation, Inc. | ||
390 | |||
391 | # This file is part of GNU tar. | ||
392 | |||
393 | @@ -405,6 +405,9 @@ m4_include([sparsemv.at]) | ||
394 | m4_include([spmvp00.at]) | ||
395 | m4_include([spmvp01.at]) | ||
396 | m4_include([spmvp10.at]) | ||
397 | +m4_include([sptrcreat.at]) | ||
398 | +m4_include([sptrdiff00.at]) | ||
399 | +m4_include([sptrdiff01.at]) | ||
400 | |||
401 | AT_BANNER([Updates]) | ||
402 | m4_include([update.at]) | ||
403 | -- | ||
404 | 2.22.0.vfs.1.1.57.gbaf16c8 | ||
405 | |||
diff --git a/meta/recipes-extended/tar/tar_1.30.bb b/meta/recipes-extended/tar/tar_1.30.bb index ab1b33b378..7cf0522455 100644 --- a/meta/recipes-extended/tar/tar_1.30.bb +++ b/meta/recipes-extended/tar/tar_1.30.bb | |||
@@ -10,6 +10,7 @@ SRC_URI = "${GNU_MIRROR}/tar/tar-${PV}.tar.bz2 \ | |||
10 | file://remove-gets.patch \ | 10 | file://remove-gets.patch \ |
11 | file://musl_dirent.patch \ | 11 | file://musl_dirent.patch \ |
12 | file://CVE-2019-9923.patch \ | 12 | file://CVE-2019-9923.patch \ |
13 | file://CVE-2018-20482.patch \ | ||
13 | " | 14 | " |
14 | 15 | ||
15 | SRC_URI[md5sum] = "8404e4c1fc5a3000228ab2b8ad674a65" | 16 | SRC_URI[md5sum] = "8404e4c1fc5a3000228ab2b8ad674a65" |