diff -Nru tar-1.28/debian/changelog tar-1.28/debian/changelog --- tar-1.28/debian/changelog 2016-11-17 16:06:07.000000000 +0000 +++ tar-1.28/debian/changelog 2020-12-16 21:40:09.000000000 +0000 @@ -1,3 +1,16 @@ +tar (1.28-2.1ubuntu0.2) xenial-security; urgency=medium + + * SECURITY UPDATE: Infinite read loop + - debian/patches/Fix-CVE-2018-20482.patch: Add handling for short read + condition in sparse_dump_region() of src/sparse.c. + - CVE-2018-20482 + * SECURITY UPDATE: NULL pointer dereference + - debian/patches/CVE-2019-9923.patch: Check for NULL return value from + find_next_block in src/sparse.c. + - CVE-2019-9923 + + -- Avital Ostromich Wed, 16 Dec 2020 16:39:55 -0500 + tar (1.28-2.1ubuntu0.1) xenial-security; urgency=medium * SECURITY UPDATE: extract pathname bypass diff -Nru tar-1.28/debian/patches/CVE-2019-9923.patch tar-1.28/debian/patches/CVE-2019-9923.patch --- tar-1.28/debian/patches/CVE-2019-9923.patch 1970-01-01 00:00:00.000000000 +0000 +++ tar-1.28/debian/patches/CVE-2019-9923.patch 2020-12-16 01:25:10.000000000 +0000 @@ -0,0 +1,30 @@ +From cb07844454d8cc9fb21f53ace75975f91185a120 Mon Sep 17 00:00:00 2001 +From: Sergey Poznyakoff +Date: Mon, 14 Jan 2019 15:22:09 +0200 +Subject: Fix possible NULL dereference (savannah bug #55369) + +* src/sparse.c (pax_decode_header): Check return from find_next_block. +--- + src/sparse.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/src/sparse.c ++++ b/src/sparse.c +@@ -1161,6 +1161,8 @@ pax_decode_header (struct tar_sparse_fil + { \ + set_next_block_after (b); \ + b = find_next_block (); \ ++ if (!b) \ ++ FATAL_ERROR ((0, 0, _("Unexpected EOF in archive"))); \ + src = b->buffer; \ + endp = b->buffer + BLOCKSIZE; \ + } \ +@@ -1173,6 +1175,8 @@ pax_decode_header (struct tar_sparse_fil + start = current_block_ordinal (); + set_next_block_after (current_header); + blk = find_next_block (); ++ if (!blk) ++ FATAL_ERROR ((0, 0, _("Unexpected EOF in archive"))); + p = blk->buffer; + COPY_BUF (blk,nbuf,p); + if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size_t))) diff -Nru tar-1.28/debian/patches/Fix-CVE-2018-20482.patch tar-1.28/debian/patches/Fix-CVE-2018-20482.patch --- tar-1.28/debian/patches/Fix-CVE-2018-20482.patch 1970-01-01 00:00:00.000000000 +0000 +++ tar-1.28/debian/patches/Fix-CVE-2018-20482.patch 2020-12-16 00:44:14.000000000 +0000 @@ -0,0 +1,358 @@ +From: Sergey Poznyakoff +Date: Thu, 27 Dec 2018 17:48:57 +0200 +Subject: Fix CVE-2018-20482 +Origin: https://git.savannah.gnu.org/cgit/tar.git/commit/?id=c15c42ccd1e2377945fd0414eca1a49294bff454 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-20482 +Bug: https://lists.gnu.org/archive/html/bug-tar/2018-12/msg00023.html +Bug-Debian: https://bugs.debian.org/917377 + +* 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. +--- + NEWS | 8 +++++- + src/sparse.c | 50 +++++++++++++++++++++++++++++++----- + tests/Makefile.am | 5 +++- + tests/sptrcreat.at | 62 +++++++++++++++++++++++++++++++++++++++++++++ + tests/sptrdiff00.at | 55 ++++++++++++++++++++++++++++++++++++++++ + tests/sptrdiff01.at | 55 ++++++++++++++++++++++++++++++++++++++++ + tests/testsuite.at | 5 +++- + 7 files changed, 231 insertions(+), 9 deletions(-) + create mode 100644 tests/sptrcreat.at + create mode 100644 tests/sptrdiff00.at + create mode 100644 tests/sptrdiff01.at + +--- a/src/sparse.c ++++ b/src/sparse.c +@@ -321,6 +321,30 @@ sparse_dump_region (struct tar_sparse_fi + 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; +@@ -358,9 +382,9 @@ sparse_extract_region (struct tar_sparse + 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) +@@ -492,6 +516,12 @@ check_sparse_region (struct tar_sparse_f + 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)]; +@@ -503,6 +533,7 @@ check_sparse_region (struct tar_sparse_f + + beg += bytes_read; + } ++ + return true; + } + +@@ -529,6 +560,7 @@ check_data_region (struct tar_sparse_fil + 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) + { +@@ -539,7 +571,11 @@ check_data_region (struct tar_sparse_fil + 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)) +@@ -1107,6 +1143,7 @@ pax_decode_header (struct tar_sparse_fil + union block *blk; + char *p; + size_t i; ++ off_t start; + + #define COPY_BUF(b,buf,src) do \ + { \ +@@ -1123,7 +1160,6 @@ pax_decode_header (struct tar_sparse_fil + if (src == endp) \ + { \ + set_next_block_after (b); \ +- file->dumped_size += BLOCKSIZE; \ + b = find_next_block (); \ + src = b->buffer; \ + endp = b->buffer + BLOCKSIZE; \ +@@ -1134,8 +1170,8 @@ pax_decode_header (struct tar_sparse_fil + dst[-1] = 0; \ + } while (0) + ++ start = current_block_ordinal (); + set_next_block_after (current_header); +- file->dumped_size += BLOCKSIZE; + blk = find_next_block (); + p = blk->buffer; + COPY_BUF (blk,nbuf,p); +@@ -1172,6 +1208,8 @@ pax_decode_header (struct tar_sparse_fil + sparse_add_map (file->stat_info, &sp); + } + set_next_block_after (blk); ++ ++ file->dumped_size += BLOCKSIZE * (current_block_ordinal () - start); + } + + return true; +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -205,6 +205,9 @@ TESTSUITE_AT = \ + spmvp00.at\ + spmvp01.at\ + spmvp10.at\ ++ sptrcreat.at\ ++ sptrdiff00.at\ ++ sptrdiff01.at\ + time01.at\ + truncate.at\ + update.at\ +--- /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 +--- /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 +--- /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 +--- a/tests/testsuite.at ++++ b/tests/testsuite.at +@@ -357,6 +357,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]) diff -Nru tar-1.28/debian/patches/series tar-1.28/debian/patches/series --- tar-1.28/debian/patches/series 2016-11-17 16:05:58.000000000 +0000 +++ tar-1.28/debian/patches/series 2020-12-16 01:25:08.000000000 +0000 @@ -4,3 +4,5 @@ files-from-and-recursive-extract.diff use-sort-in-t-dir-tests.diff CVE-2016-6321.patch +Fix-CVE-2018-20482.patch +CVE-2019-9923.patch