summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Tran <dantran@microsoft.com>2019-10-29 20:34:26 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2019-12-16 23:11:10 +0000
commit4c556ab0d57ec22d335394580557d3b663da43b2 (patch)
treefa9c9cdf38d88b8939004370761a0b0828b8c4a9
parenta802677332feeaf3c09b6c153db48b541c88eed1 (diff)
downloadpoky-4c556ab0d57ec22d335394580557d3b663da43b2.tar.gz
tar: Fix CVE-2018-20482
(From OE-Core rev: 95ab1519ea5f1a0ed73f6f484bcf15fde5de8140) Signed-off-by: Dan Tran <dantran@microsoft.com> Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-extended/tar/tar/CVE-2018-20482.patch405
-rw-r--r--meta/recipes-extended/tar/tar_1.30.bb1
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 @@
1From 331be56598b284d41370c67046df25673b040a55 Mon Sep 17 00:00:00 2001
2From: Sergey Poznyakoff <gray@gnu.org>
3Date: Thu, 27 Dec 2018 17:48:57 +0200
4Subject: [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.
9Handle 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
18CVE: CVE-2018-20482
19Upstream-Status: Backport
20[http://git.savannah.gnu.org/cgit/tar.git/commit/?id=c15c42ccd1e2377945fd0414eca1a49294bff454]
21
22Signed-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
35diff --git a/src/sparse.c b/src/sparse.c
36index 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 (&current_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;
168diff --git a/tests/Makefile.am b/tests/Makefile.am
169index 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\
190diff --git a/tests/sptrcreat.at b/tests/sptrcreat.at
191new file mode 100644
192index 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
258diff --git a/tests/sptrdiff00.at b/tests/sptrdiff00.at
259new file mode 100644
260index 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
319diff --git a/tests/sptrdiff01.at b/tests/sptrdiff01.at
320new file mode 100644
321index 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
380diff --git a/tests/testsuite.at b/tests/testsuite.at
381index 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--
4042.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
15SRC_URI[md5sum] = "8404e4c1fc5a3000228ab2b8ad674a65" 16SRC_URI[md5sum] = "8404e4c1fc5a3000228ab2b8ad674a65"