From 0111044f9d11f2a7821024385620e6e342acdf43 Mon Sep 17 00:00:00 2001 From: tong_1001 Date: Wed, 14 Apr 2021 10:57:57 +0800 Subject: [PATCH 1/2] fix CVE-2021-20193 (cherry picked from commit f747e9dc1e7eff6295113c9d33a49f4cd667143b) --- backport-CVE-2021-20193.patch | 129 ++++++++++++++++++++++++++++++++++ tar.spec | 11 ++- 2 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 backport-CVE-2021-20193.patch diff --git a/backport-CVE-2021-20193.patch b/backport-CVE-2021-20193.patch new file mode 100644 index 0000000..c18521b --- /dev/null +++ b/backport-CVE-2021-20193.patch @@ -0,0 +1,129 @@ +From d9d4435692150fa8ff68e1b1a473d187cc3fd777 Mon Sep 17 00:00:00 2001 +From: Sergey Poznyakoff +Date: Sun, 17 Jan 2021 20:41:11 +0200 +Subject: Fix memory leak in read_header + +https://git.savannah.gnu.org/cgit/tar.git/commit/?id=d9d4435692150fa8ff68e1b1a473d187cc3fd777 + +Bug reported in https://savannah.gnu.org/bugs/?59897 + +* src/list.c (read_header): Don't return directly from the loop. +Instead set the status and break. Return the status. Free +next_long_name and next_long_link before returning. +--- + src/list.c | 40 ++++++++++++++++++++++++++++------------ + 1 file changed, 28 insertions(+), 12 deletions(-) + +diff --git a/src/list.c b/src/list.c +index e40a5c8..d7ef441 100644 +--- a/src/list.c ++++ b/src/list.c +@@ -408,26 +408,27 @@ read_header (union block **return_block, struct tar_stat_info *info, + enum read_header_mode mode) + { + union block *header; +- union block *header_copy; + char *bp; + union block *data_block; + size_t size, written; +- union block *next_long_name = 0; +- union block *next_long_link = 0; ++ union block *next_long_name = NULL; ++ union block *next_long_link = NULL; + size_t next_long_name_blocks = 0; + size_t next_long_link_blocks = 0; +- ++ enum read_header status = HEADER_SUCCESS; ++ + while (1) + { +- enum read_header status; +- + header = find_next_block (); + *return_block = header; + if (!header) +- return HEADER_END_OF_FILE; ++ { ++ status = HEADER_END_OF_FILE; ++ break; ++ } + + if ((status = tar_checksum (header, false)) != HEADER_SUCCESS) +- return status; ++ break; + + /* Good block. Decode file size and return. */ + +@@ -437,7 +438,10 @@ read_header (union block **return_block, struct tar_stat_info *info, + { + info->stat.st_size = OFF_FROM_HEADER (header->header.size); + if (info->stat.st_size < 0) +- return HEADER_FAILURE; ++ { ++ status = HEADER_FAILURE; ++ break; ++ } + } + + if (header->header.typeflag == GNUTYPE_LONGNAME +@@ -447,10 +451,14 @@ read_header (union block **return_block, struct tar_stat_info *info, + || header->header.typeflag == SOLARIS_XHDTYPE) + { + if (mode == read_header_x_raw) +- return HEADER_SUCCESS_EXTENDED; ++ { ++ status = HEADER_SUCCESS_EXTENDED; ++ break; ++ } + else if (header->header.typeflag == GNUTYPE_LONGNAME + || header->header.typeflag == GNUTYPE_LONGLINK) + { ++ union block *header_copy; + size_t name_size = info->stat.st_size; + size_t n = name_size % BLOCKSIZE; + size = name_size + BLOCKSIZE; +@@ -517,7 +525,10 @@ read_header (union block **return_block, struct tar_stat_info *info, + xheader_decode_global (&xhdr); + xheader_destroy (&xhdr); + if (mode == read_header_x_global) +- return HEADER_SUCCESS_EXTENDED; ++ { ++ status = HEADER_SUCCESS_EXTENDED; ++ break; ++ } + } + + /* Loop! */ +@@ -536,6 +547,7 @@ read_header (union block **return_block, struct tar_stat_info *info, + name = next_long_name->buffer + BLOCKSIZE; + recent_long_name = next_long_name; + recent_long_name_blocks = next_long_name_blocks; ++ next_long_name = NULL; + } + else + { +@@ -567,6 +579,7 @@ read_header (union block **return_block, struct tar_stat_info *info, + name = next_long_link->buffer + BLOCKSIZE; + recent_long_link = next_long_link; + recent_long_link_blocks = next_long_link_blocks; ++ next_long_link = NULL; + } + else + { +@@ -578,9 +591,12 @@ read_header (union block **return_block, struct tar_stat_info *info, + } + assign_string (&info->link_name, name); + +- return HEADER_SUCCESS; ++ break; + } + } ++ free (next_long_name); ++ free (next_long_link); ++ return status; + } + + #define ISOCTAL(c) ((c)>='0'&&(c)<='7') +-- +cgit v1.2.1 + diff --git a/tar.spec b/tar.spec index 49c7a89..d5d62f3 100644 --- a/tar.spec +++ b/tar.spec @@ -1,6 +1,6 @@ Name: tar Version: 1.32 -Release: 1 +Release: 2 Epoch: 2 Summary: An organized and systematic method of controlling a large amount of data License: GPLv3+ @@ -8,6 +8,8 @@ URL: http://www.gnu.org/software/tar/ Source0: https://ftp.gnu.org/gnu/tar/tar-%{version}.tar.xz Source1: https://ftp.gnu.org/gnu/tar/tar-%{version}.tar.xz.sig +Patch6000: backport-CVE-2021-20193.patch + BuildRequires: autoconf automake texinfo gettext libacl-devel attr acl policycoreutils Provides: bundled(gnulib) /bin/tar /bin/gtar @@ -74,8 +76,11 @@ make check %{_infodir}/tar.info* %changelog -* Tue Aug 04 2020 shanzhikun - 2:1.32-1 -- upgrade tar to 1.32. +* Wed Apr 14 2021 shixuantong - 1.32-2 +- fix CVE-2021-20193 + +* Mon Jul 27 2020 shixuantong - 1.32-1 +- update to 1.32-1 * Tue Feb 18 2020 openEuler Buildteam - 2:1.30-11 - Enable check -- Gitee From 37aa6811ad14bad98952239bdb8a34d538d4f422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A1=90=E5=B0=8F=E5=93=A5?= Date: Wed, 14 Apr 2021 14:15:05 +0800 Subject: [PATCH 2/2] update tar.spec. --- tar.spec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tar.spec b/tar.spec index d5d62f3..ec75682 100644 --- a/tar.spec +++ b/tar.spec @@ -76,11 +76,11 @@ make check %{_infodir}/tar.info* %changelog -* Wed Apr 14 2021 shixuantong - 1.32-2 +* Wed Apr 14 2021 shixuantong - 2:1.32-2 - fix CVE-2021-20193 -* Mon Jul 27 2020 shixuantong - 1.32-1 -- update to 1.32-1 +* Tue Aug 04 2020 shanzhikun - 2:1.32-1 +- upgrade tar to 1.32. * Tue Feb 18 2020 openEuler Buildteam - 2:1.30-11 - Enable check -- Gitee