mirror of
https://git.yoctoproject.org/poky
synced 2026-04-20 00:32:13 +02:00
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>
This commit is contained in:
405
meta/recipes-extended/tar/tar/CVE-2018-20482.patch
Normal file
405
meta/recipes-extended/tar/tar/CVE-2018-20482.patch
Normal file
@@ -0,0 +1,405 @@
|
||||
From 331be56598b284d41370c67046df25673b040a55 Mon Sep 17 00:00:00 2001
|
||||
From: Sergey Poznyakoff <gray@gnu.org>
|
||||
Date: Thu, 27 Dec 2018 17:48:57 +0200
|
||||
Subject: [PATCH] Fix CVE-2018-20482
|
||||
|
||||
* NEWS: Update.
|
||||
* src/sparse.c (sparse_dump_region): Handle short read condition.
|
||||
(sparse_extract_region,check_data_region): Fix dumped_size calculation.
|
||||
Handle short read condition.
|
||||
(pax_decode_header): Fix dumped_size calculation.
|
||||
* tests/Makefile.am: Add new testcases.
|
||||
* tests/testsuite.at: Likewise.
|
||||
|
||||
* tests/sptrcreat.at: New file.
|
||||
* tests/sptrdiff00.at: New file.
|
||||
* tests/sptrdiff01.at: New file.
|
||||
|
||||
CVE: CVE-2018-20482
|
||||
Upstream-Status: Backport
|
||||
[http://git.savannah.gnu.org/cgit/tar.git/commit/?id=c15c42ccd1e2377945fd0414eca1a49294bff454]
|
||||
|
||||
Signed-off-by: Dan Tran <dantran@microsoft.com>
|
||||
---
|
||||
src/sparse.c | 50 +++++++++++++++++++++++++++++++-----
|
||||
tests/Makefile.am | 5 +++-
|
||||
tests/sptrcreat.at | 62 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
tests/sptrdiff00.at | 55 ++++++++++++++++++++++++++++++++++++++++
|
||||
tests/sptrdiff01.at | 55 ++++++++++++++++++++++++++++++++++++++++
|
||||
tests/testsuite.at | 5 +++-
|
||||
6 files changed, 224 insertions(+), 8 deletions(-)
|
||||
create mode 100644 tests/sptrcreat.at
|
||||
create mode 100644 tests/sptrdiff00.at
|
||||
create mode 100644 tests/sptrdiff01.at
|
||||
|
||||
diff --git a/src/sparse.c b/src/sparse.c
|
||||
index 0830f62..e8e8259 100644
|
||||
--- a/src/sparse.c
|
||||
+++ b/src/sparse.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Functions for dealing with sparse files
|
||||
|
||||
- Copyright 2003-2007, 2010, 2013-2017 Free Software Foundation, Inc.
|
||||
+ Copyright 2003-2007, 2010, 2013-2018 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
@@ -427,6 +427,30 @@ sparse_dump_region (struct tar_sparse_file *file, size_t i)
|
||||
bufsize);
|
||||
return false;
|
||||
}
|
||||
+ else if (bytes_read == 0)
|
||||
+ {
|
||||
+ char buf[UINTMAX_STRSIZE_BOUND];
|
||||
+ struct stat st;
|
||||
+ size_t n;
|
||||
+ if (fstat (file->fd, &st) == 0)
|
||||
+ n = file->stat_info->stat.st_size - st.st_size;
|
||||
+ else
|
||||
+ n = file->stat_info->stat.st_size
|
||||
+ - (file->stat_info->sparse_map[i].offset
|
||||
+ + file->stat_info->sparse_map[i].numbytes
|
||||
+ - bytes_left);
|
||||
+
|
||||
+ WARNOPT (WARN_FILE_SHRANK,
|
||||
+ (0, 0,
|
||||
+ ngettext ("%s: File shrank by %s byte; padding with zeros",
|
||||
+ "%s: File shrank by %s bytes; padding with zeros",
|
||||
+ n),
|
||||
+ quotearg_colon (file->stat_info->orig_file_name),
|
||||
+ STRINGIFY_BIGINT (n, buf)));
|
||||
+ if (! ignore_failed_read_option)
|
||||
+ set_exit_status (TAREXIT_DIFFERS);
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
memset (blk->buffer + bytes_read, 0, BLOCKSIZE - bytes_read);
|
||||
bytes_left -= bytes_read;
|
||||
@@ -464,9 +488,9 @@ sparse_extract_region (struct tar_sparse_file *file, size_t i)
|
||||
return false;
|
||||
}
|
||||
set_next_block_after (blk);
|
||||
+ file->dumped_size += BLOCKSIZE;
|
||||
count = blocking_write (file->fd, blk->buffer, wrbytes);
|
||||
write_size -= count;
|
||||
- file->dumped_size += count;
|
||||
mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
|
||||
file->offset += count;
|
||||
if (count != wrbytes)
|
||||
@@ -598,6 +622,12 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
|
||||
rdsize);
|
||||
return false;
|
||||
}
|
||||
+ else if (bytes_read == 0)
|
||||
+ {
|
||||
+ report_difference (file->stat_info, _("Size differs"));
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
if (!zero_block_p (diff_buffer, bytes_read))
|
||||
{
|
||||
char begbuf[INT_BUFSIZE_BOUND (off_t)];
|
||||
@@ -609,6 +639,7 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
|
||||
|
||||
beg += bytes_read;
|
||||
}
|
||||
+
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -635,6 +666,7 @@ check_data_region (struct tar_sparse_file *file, size_t i)
|
||||
return false;
|
||||
}
|
||||
set_next_block_after (blk);
|
||||
+ file->dumped_size += BLOCKSIZE;
|
||||
bytes_read = safe_read (file->fd, diff_buffer, rdsize);
|
||||
if (bytes_read == SAFE_READ_ERROR)
|
||||
{
|
||||
@@ -645,7 +677,11 @@ check_data_region (struct tar_sparse_file *file, size_t i)
|
||||
rdsize);
|
||||
return false;
|
||||
}
|
||||
- file->dumped_size += bytes_read;
|
||||
+ else if (bytes_read == 0)
|
||||
+ {
|
||||
+ report_difference (¤t_stat_info, _("Size differs"));
|
||||
+ return false;
|
||||
+ }
|
||||
size_left -= bytes_read;
|
||||
mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
|
||||
if (memcmp (blk->buffer, diff_buffer, rdsize))
|
||||
@@ -1213,7 +1249,8 @@ pax_decode_header (struct tar_sparse_file *file)
|
||||
union block *blk;
|
||||
char *p;
|
||||
size_t i;
|
||||
-
|
||||
+ off_t start;
|
||||
+
|
||||
#define COPY_BUF(b,buf,src) do \
|
||||
{ \
|
||||
char *endp = b->buffer + BLOCKSIZE; \
|
||||
@@ -1229,7 +1266,6 @@ pax_decode_header (struct tar_sparse_file *file)
|
||||
if (src == endp) \
|
||||
{ \
|
||||
set_next_block_after (b); \
|
||||
- file->dumped_size += BLOCKSIZE; \
|
||||
b = find_next_block (); \
|
||||
if (!b) \
|
||||
FATAL_ERROR ((0, 0, _("Unexpected EOF in archive"))); \
|
||||
@@ -1242,8 +1278,8 @@ pax_decode_header (struct tar_sparse_file *file)
|
||||
dst[-1] = 0; \
|
||||
} while (0)
|
||||
|
||||
+ start = current_block_ordinal ();
|
||||
set_next_block_after (current_header);
|
||||
- file->dumped_size += BLOCKSIZE;
|
||||
blk = find_next_block ();
|
||||
if (!blk)
|
||||
FATAL_ERROR ((0, 0, _("Unexpected EOF in archive")));
|
||||
@@ -1282,6 +1318,8 @@ pax_decode_header (struct tar_sparse_file *file)
|
||||
sparse_add_map (file->stat_info, &sp);
|
||||
}
|
||||
set_next_block_after (blk);
|
||||
+
|
||||
+ file->dumped_size += BLOCKSIZE * (current_block_ordinal () - start);
|
||||
}
|
||||
|
||||
return true;
|
||||
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||
index 2d7939d..ac3b6e7 100644
|
||||
--- a/tests/Makefile.am
|
||||
+++ b/tests/Makefile.am
|
||||
@@ -1,6 +1,6 @@
|
||||
# Makefile for GNU tar regression tests.
|
||||
|
||||
-# Copyright 1996-1997, 1999-2001, 2003-2007, 2009, 2012-2015 Free Software
|
||||
+# Copyright 1996-1997, 1999-2001, 2003-2007, 2009, 2012-2018 Free Software
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
@@ -228,6 +228,9 @@ TESTSUITE_AT = \
|
||||
spmvp00.at\
|
||||
spmvp01.at\
|
||||
spmvp10.at\
|
||||
+ sptrcreat.at\
|
||||
+ sptrdiff00.at\
|
||||
+ sptrdiff01.at\
|
||||
time01.at\
|
||||
time02.at\
|
||||
truncate.at\
|
||||
diff --git a/tests/sptrcreat.at b/tests/sptrcreat.at
|
||||
new file mode 100644
|
||||
index 0000000..8e28f0e
|
||||
--- /dev/null
|
||||
+++ b/tests/sptrcreat.at
|
||||
@@ -0,0 +1,62 @@
|
||||
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
+
|
||||
+# Test suite for GNU tar.
|
||||
+# Copyright 2018 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This file is part of GNU tar.
|
||||
+
|
||||
+# GNU tar is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+
|
||||
+# GNU tar is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+# Tar up to 1.30 would loop endlessly if a sparse file had been truncated
|
||||
+# while being archived (with --sparse flag).
|
||||
+#
|
||||
+# The bug has been assigned id CVE-2018-20482 (on the grounds that it is a
|
||||
+# denial of service possibility).
|
||||
+#
|
||||
+# Reported by: Chris Siebenmann <cks.gnutar-01@cs.toronto.edu>
|
||||
+# References: <20181226223948.781EB32008E@apps1.cs.toronto.edu>,
|
||||
+# <http://lists.gnu.org/archive/html/bug-tar/2018-12/msg00023.html>
|
||||
+# <https://utcc.utoronto.ca/~cks/space/blog/sysadmin/TarFindingTruncateBug>
|
||||
+# <https://nvd.nist.gov/vuln/detail/CVE-2018-20482>
|
||||
+
|
||||
+AT_SETUP([sparse file truncated while archiving])
|
||||
+AT_KEYWORDS([truncate filechange sparse sptr sptrcreat])
|
||||
+
|
||||
+AT_TAR_CHECK([
|
||||
+genfile --sparse --block-size=1024 --file foo \
|
||||
+ 0 ABCDEFGHIJ 1M ABCDEFGHIJ 10M ABCDEFGHIJ 200M ABCDEFGHIJ
|
||||
+genfile --file baz
|
||||
+genfile --run --checkpoint 3 --length 200m --truncate foo -- \
|
||||
+ tar --checkpoint=1 \
|
||||
+ --checkpoint-action=echo \
|
||||
+ --checkpoint-action=sleep=1 \
|
||||
+ --sparse -vcf bar foo baz
|
||||
+echo Exit status: $?
|
||||
+echo separator
|
||||
+genfile --file foo --seek 200m --length 11575296 --pattern=zeros
|
||||
+tar dvf bar],
|
||||
+[1],
|
||||
+[foo
|
||||
+baz
|
||||
+Exit status: 1
|
||||
+separator
|
||||
+foo
|
||||
+foo: Mod time differs
|
||||
+baz
|
||||
+],
|
||||
+[tar: foo: File shrank by 11575296 bytes; padding with zeros
|
||||
+],
|
||||
+[],[],[posix, gnu, oldgnu])
|
||||
+
|
||||
+AT_CLEANUP
|
||||
diff --git a/tests/sptrdiff00.at b/tests/sptrdiff00.at
|
||||
new file mode 100644
|
||||
index 0000000..c410561
|
||||
--- /dev/null
|
||||
+++ b/tests/sptrdiff00.at
|
||||
@@ -0,0 +1,55 @@
|
||||
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
+#
|
||||
+# Test suite for GNU tar.
|
||||
+# Copyright 2018 Free Software Foundation, Inc.
|
||||
+#
|
||||
+# This file is part of GNU tar.
|
||||
+#
|
||||
+# GNU tar is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# GNU tar is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+# While fixing CVE-2018-20482 (see sptrcreat.at) it has been discovered
|
||||
+# that similar bug exists in file checking code (tar d).
|
||||
+# This test case checks if tar correctly handles a short read condition
|
||||
+# appearing in check_sparse_region.
|
||||
+
|
||||
+AT_SETUP([file truncated in sparse region while comparing])
|
||||
+AT_KEYWORDS([truncate filechange sparse sptr sptrdiff diff])
|
||||
+
|
||||
+# This triggers short read in check_sparse_region.
|
||||
+AT_TAR_CHECK([
|
||||
+genfile --sparse --block-size=1024 --file foo \
|
||||
+ 0 ABCDEFGHIJ 1M ABCDEFGHIJ 10M ABCDEFGHIJ 200M ABCDEFGHIJ
|
||||
+genfile --file baz
|
||||
+echo creating
|
||||
+tar --sparse -vcf bar foo baz
|
||||
+echo comparing
|
||||
+genfile --run --checkpoint 3 --length 200m --truncate foo -- \
|
||||
+ tar --checkpoint=1 \
|
||||
+ --checkpoint-action=echo='Write checkpoint %u' \
|
||||
+ --checkpoint-action=sleep=1 \
|
||||
+ --sparse -vdf bar
|
||||
+],
|
||||
+[1],
|
||||
+[creating
|
||||
+foo
|
||||
+baz
|
||||
+comparing
|
||||
+foo
|
||||
+foo: Size differs
|
||||
+baz
|
||||
+],
|
||||
+[],
|
||||
+[],[],[posix, gnu, oldgnu])
|
||||
+
|
||||
+AT_CLEANUP
|
||||
diff --git a/tests/sptrdiff01.at b/tests/sptrdiff01.at
|
||||
new file mode 100644
|
||||
index 0000000..2da2267
|
||||
--- /dev/null
|
||||
+++ b/tests/sptrdiff01.at
|
||||
@@ -0,0 +1,55 @@
|
||||
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
+#
|
||||
+# Test suite for GNU tar.
|
||||
+# Copyright 2018 Free Software Foundation, Inc.
|
||||
+#
|
||||
+# This file is part of GNU tar.
|
||||
+#
|
||||
+# GNU tar is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# GNU tar is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+# While fixing CVE-2018-20482 (see sptrcreat.at) it has been discovered
|
||||
+# that similar bug exists in file checking code (tar d).
|
||||
+# This test case checks if tar correctly handles a short read condition
|
||||
+# appearing in check_data_region.
|
||||
+
|
||||
+AT_SETUP([file truncated in data region while comparing])
|
||||
+AT_KEYWORDS([truncate filechange sparse sptr sptrdiff diff])
|
||||
+
|
||||
+# This triggers short read in check_data_region.
|
||||
+AT_TAR_CHECK([
|
||||
+genfile --sparse --block-size=1024 --file foo \
|
||||
+ 0 ABCDEFGHIJ 1M ABCDEFGHIJ 10M ABCDEFGHIJ 200M ABCDEFGHIJ
|
||||
+genfile --file baz
|
||||
+echo creating
|
||||
+tar --sparse -vcf bar foo baz
|
||||
+echo comparing
|
||||
+genfile --run --checkpoint 5 --length 221278210 --truncate foo -- \
|
||||
+ tar --checkpoint=1 \
|
||||
+ --checkpoint-action=echo='Write checkpoint %u' \
|
||||
+ --checkpoint-action=sleep=1 \
|
||||
+ --sparse -vdf bar
|
||||
+],
|
||||
+[1],
|
||||
+[creating
|
||||
+foo
|
||||
+baz
|
||||
+comparing
|
||||
+foo
|
||||
+foo: Size differs
|
||||
+baz
|
||||
+],
|
||||
+[],
|
||||
+[],[],[posix, gnu, oldgnu])
|
||||
+
|
||||
+AT_CLEANUP
|
||||
diff --git a/tests/testsuite.at b/tests/testsuite.at
|
||||
index 2a83757..23386f7 100644
|
||||
--- a/tests/testsuite.at
|
||||
+++ b/tests/testsuite.at
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
-# Copyright 2004-2008, 2010-2017 Free Software Foundation, Inc.
|
||||
+# Copyright 2004-2008, 2010-2018 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
@@ -405,6 +405,9 @@ m4_include([sparsemv.at])
|
||||
m4_include([spmvp00.at])
|
||||
m4_include([spmvp01.at])
|
||||
m4_include([spmvp10.at])
|
||||
+m4_include([sptrcreat.at])
|
||||
+m4_include([sptrdiff00.at])
|
||||
+m4_include([sptrdiff01.at])
|
||||
|
||||
AT_BANNER([Updates])
|
||||
m4_include([update.at])
|
||||
--
|
||||
2.22.0.vfs.1.1.57.gbaf16c8
|
||||
|
||||
@@ -10,6 +10,7 @@ SRC_URI = "${GNU_MIRROR}/tar/tar-${PV}.tar.bz2 \
|
||||
file://remove-gets.patch \
|
||||
file://musl_dirent.patch \
|
||||
file://CVE-2019-9923.patch \
|
||||
file://CVE-2018-20482.patch \
|
||||
"
|
||||
|
||||
SRC_URI[md5sum] = "8404e4c1fc5a3000228ab2b8ad674a65"
|
||||
|
||||
Reference in New Issue
Block a user