From 59c060f3119e9a9cb85b78bc5c7978b0f57198ce Mon Sep 17 00:00:00 2001 From: dogsheng <960055655@qq.com> Date: Wed, 25 Dec 2019 16:08:38 +0800 Subject: [PATCH] Package init --- Fix-CVE-2018-20482.patch | 465 +++++++++++++++++++++++++++++++++++++++ tar.spec | 51 +++-- 2 files changed, 492 insertions(+), 24 deletions(-) create mode 100644 Fix-CVE-2018-20482.patch diff --git a/Fix-CVE-2018-20482.patch b/Fix-CVE-2018-20482.patch new file mode 100644 index 0000000..65e209d --- /dev/null +++ b/Fix-CVE-2018-20482.patch @@ -0,0 +1,465 @@ +From fd555fc06bfb4eae3eb48fbc150d20a4dda0d150 Mon Sep 17 00:00:00 2001 +From: Sergey Poznyakoff +Date: Thu, 27 Dec 2018 17:48:57 +0200 +Subject: [PATCH] Fixed a denial of service when the '--sparse' option +mishandles file shrinkage during read access(CVE-2018-20482) +https://github.com/praiskup/tar/commit/c15c42ccd1e2377945fd0414eca1a49294bff454 + +Signed-off-by: fangyufa1 +--- + NEWS | 32 +++++++++++++++++- + src/sparse.c | 82 +++++++++++++++++++++++++++++---------------- + tests/Makefile.am | 5 ++- + tests/sptrcreat.at | 62 ++++++++++++++++++++++++++++++++++ + tests/sptrdiff00.at | 55 ++++++++++++++++++++++++++++++ + tests/sptrdiff01.at | 55 ++++++++++++++++++++++++++++++ + tests/testsuite.at | 5 ++- + 7 files changed, 264 insertions(+), 32 deletions(-) + create mode 100644 tests/sptrcreat.at + create mode 100644 tests/sptrdiff00.at + create mode 100644 tests/sptrdiff01.at + +diff --git a/NEWS b/NEWS +index cd15fa1..283c376 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,7 +1,37 @@ +-GNU tar NEWS - User visible changes. 2017-12-17 ++GNU tar NEWS - User visible changes. 2018-12-27 + Please send GNU tar bug reports to + + ++version 1.30.90 (Git) ++ ++* Fix heap-buffer-overrun with --one-top-level. ++Bug introduced with the addition of that option in 1.28. ++ ++* Support for zstd compression ++ ++New option '--zstd' instructs tar to use zstd as compression program. ++When listing, extractng and comparing, zstd compressed archives are ++recognized automatically. ++When '-a' option is in effect, zstd compression is selected if the ++destination archive name ends in '.zst' or '.tzst'. ++ ++* The -K option interacts properly with member names given in the command line ++ ++Names of members to extract can be specified along with the "-K NAME" ++option. In this case, tar will extract NAME and those of named members ++that appear in the archive after it, which is consistent with the ++semantics of the option. ++ ++Previous versions of tar extracted NAME, those of named members that ++appeared before it, and everything after it. ++ ++* Fix CVE-2018-20482 ++ ++When creating archives with the --sparse option, previous versions of ++tar would loop endlessly if a sparse file had been truncated while ++being archived. ++ ++ + version 1.30 - Sergey Poznyakoff, 2017-12-17 + + * Member names containing '..' components are now skipped when extracting. +diff --git a/src/sparse.c b/src/sparse.c +index 6ec069d..726facd 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 +@@ -428,16 +428,30 @@ sparse_dump_region (struct tar_sparse_file *file, size_t i) + bufsize); + return false; + } +- if (bytes_read == 0) +- { +- char buf[UINTMAX_STRSIZE_BOUND]; +- FATAL_ERROR ((0, 0, +- ngettext ("%s: File shrank by %s byte", +- "%s: File shrank by %s bytes", +- bytes_left), +- quotearg_colon (file_name), +- offtostr (bytes_left, buf))); +- } ++ 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_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; +@@ -475,9 +489,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) +@@ -610,20 +624,24 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end) + offset, rdsize); + return false; + } +- +- if (bytes_read == 0 +- || !zero_block_p (diff_buffer, bytes_read)) +- { +- char begbuf[INT_BUFSIZE_BOUND (off_t)]; +- const char *msg = bytes_read ? _("File fragment at %s is not a hole") +- : _("Hole starting at %s is truncated"); +- +- report_difference (file->stat_info, msg, offtostr (beg, begbuf)); +- 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)]; ++ report_difference (file->stat_info, ++ _("File fragment at %s is not a hole"), ++ offtostr (offset, begbuf)); ++ return false; ++ } + + offset += bytes_read; + } ++ + return true; + } + +@@ -650,6 +668,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) + { +@@ -660,11 +679,14 @@ 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 (bytes_read == 0 +- || memcmp (blk->buffer, diff_buffer, bytes_read)) ++ if (memcmp (blk->buffer, diff_buffer, bytes_read)) + { + report_difference (file->stat_info, _("Contents differ")); + return false; +@@ -1229,7 +1251,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; \ +@@ -1245,7 +1268,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"))); \ +@@ -1258,8 +1280,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"))); +@@ -1298,6 +1320,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 . ++ ++# 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 ++# References: <20181226223948.781EB32008E@apps1.cs.toronto.edu>, ++# ++# ++# ++ ++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 . ++ ++# 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 . ++ ++# 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.19.1 + diff --git a/tar.spec b/tar.spec index 924a7e2..948279f 100644 --- a/tar.spec +++ b/tar.spec @@ -1,6 +1,6 @@ Name: tar Version: 1.30 -Release: 7 +Release: 8 Epoch: 2 Summary: An organized and systematic method of controlling a large amount of data License: GPLv3+ @@ -21,27 +21,28 @@ Patch0006: tar-1.28-sparse-inf-loops.patch Patch0007: tar-1.30-tests-difflink.patch Patch0008: tar-1.30-tests-dirrem.patch -Patch9000: Rewrite-struct-tm-formatting.patch -Patch9001: maint-avoid-warnings-from-upcoming-GCC8.patch -Patch9002: maint-avoid-Wstringop-truncation-warnings-upcoming-G.patch -Patch9003: maint-avoid-Wstringop-truncation-warnings-from-upcom.patch -Patch9004: one-top-level-avoid-a-heap-buffer-overflow.patch -Patch9005: Avoid-some-resource-leaks.patch -Patch9006: Report-race-on-systems-without-O_DIRECTORY.patch -Patch9007: Fix-double-free-introduced-by-577dc345.patch -Patch9008: Fix-improper-memory-access.patch -Patch9009: Fix-buffer-overflow.patch -Patch9010: Reject-pax-options-starting-with-equals-sign.patch -Patch9011: Fix-error-handling-when-reading-incremental-snapshot.patch -Patch9012: Fix-semantics-of-K-used-together-with-explicit-membe.patch -Patch9013: Bugfix.patch -Patch9014: Disallow-modifications-to-the-global-pax-extended-he.patch -Patch9015: Work-over-a-bug-in-gnulib-error.patch -Patch9016: Remove-erroneous-abort-call.patch -Patch9017: Fix-iconv-usage.patch -Patch9018: Fix-compilation-without-iconv.patch -Patch9019: Fix-build-on-AIX.patch -Patch9020: Fix-possible-NULL-dereference-savannah-bug-55369.patch +Patch6000: Rewrite-struct-tm-formatting.patch +Patch6001: maint-avoid-warnings-from-upcoming-GCC8.patch +Patch6002: maint-avoid-Wstringop-truncation-warnings-upcoming-G.patch +Patch6003: maint-avoid-Wstringop-truncation-warnings-from-upcom.patch +Patch6004: one-top-level-avoid-a-heap-buffer-overflow.patch +Patch6005: Avoid-some-resource-leaks.patch +Patch6006: Report-race-on-systems-without-O_DIRECTORY.patch +Patch6007: Fix-double-free-introduced-by-577dc345.patch +Patch6008: Fix-improper-memory-access.patch +Patch6009: Fix-buffer-overflow.patch +Patch6010: Reject-pax-options-starting-with-equals-sign.patch +Patch6011: Fix-error-handling-when-reading-incremental-snapshot.patch +Patch6012: Fix-semantics-of-K-used-together-with-explicit-membe.patch +Patch6013: Bugfix.patch +Patch6014: Disallow-modifications-to-the-global-pax-extended-he.patch +Patch6015: Work-over-a-bug-in-gnulib-error.patch +Patch6016: Remove-erroneous-abort-call.patch +Patch6017: Fix-iconv-usage.patch +Patch6018: Fix-compilation-without-iconv.patch +Patch6019: Fix-build-on-AIX.patch +Patch6020: Fix-possible-NULL-dereference-savannah-bug-55369.patch +Patch6021: Fix-CVE-2018-20482.patch %description GNU Tar provides the ability to create tar archives, as well as various other @@ -99,6 +100,8 @@ make check %{_infodir}/tar.info* %changelog -* Tue Sep 10 2019 Huiming Xie - 2:1.30.7 -- Package init +* Sat Dec 21 2019 openEuler Buildteam - 2:1.30-8 +- Fix CVE-2018-20482 +* Tue Sep 10 2019 Huiming Xie - 2:1.30-7 +- Package init