diff --git a/dist b/dist index 9c0e36ec42a2d9bfefacb21ac6354c9ddd910533..1fe92cf0fdf9c2625d878a2ace258f64c1e8ca44 100644 --- a/dist +++ b/dist @@ -1 +1 @@ -an8 +an8_10 diff --git a/tar-1.30-filerem01.at-swap-actions.patch b/tar-1.30-filerem01.at-swap-actions.patch new file mode 100644 index 0000000000000000000000000000000000000000..44e43e7af693dddb8dc0a39fe69274a3938c6441 --- /dev/null +++ b/tar-1.30-filerem01.at-swap-actions.patch @@ -0,0 +1,15 @@ +diff --git a/tests/filerem01.at b/tests/filerem01.at +index bf020538..6a9893a6 100644 +--- a/tests/filerem01.at ++++ b/tests/filerem01.at +@@ -43,8 +43,8 @@ genfile --file dir/file1 + genfile --file dir/sub/file2 + + genfile --run --checkpoint=3 --unlink dir/file1 -- \ +- tar --blocking-factor=1 --checkpoint=1 --checkpoint-action='sleep=1' \ +- --checkpoint-action='echo' -c -f archive.tar \ ++ tar --blocking-factor=1 --checkpoint=1 --checkpoint-action='echo' \ ++ --checkpoint-action='sleep=1' -c -f archive.tar \ + --listed-incremental db -v dir >/dev/null + ], + [1], diff --git a/tar-1.30-no-overwrite-dir-no-overwrite-even-temporarily.patch b/tar-1.30-no-overwrite-dir-no-overwrite-even-temporarily.patch new file mode 100644 index 0000000000000000000000000000000000000000..a6de88c45295e94142f643504e92cffb67e8f9ad --- /dev/null +++ b/tar-1.30-no-overwrite-dir-no-overwrite-even-temporarily.patch @@ -0,0 +1,182 @@ +From d4f7fd373e79dddd7f411589808d80ac8032e6e3 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Sat, 26 Jul 2025 21:41:23 -0700 +Subject: [PATCH] --no-overwrite-dir no overwrite even temporarily + +Problem and fix reported by Pavel Cahyna in +https://lists.gnu.org/r/bug-tar/2025-01/msg00000.html +* src/extract.c (extract_dir): With --no-overwrite-dir, +skip the chmod if the directory already exists. +* tests/extrac23.at (--no-overwrite-dir on empty directory): +Move the part of the test that looks at a nonempty directory ... +* tests/extrac30.at: ... to this new file, because the test now +must be run as non-root. Adjust the test to match the new behavior. +* tests/Makefile.am (TESTSUITE_AT), tests/testsuite.at: Add it. +--- + src/extract.c | 25 ------------------------ + tests/Makefile.am | 1 + + tests/extrac23.at | 16 +--------------- + tests/extrac30.at | 47 ++++++++++++++++++++++++++++++++++++++++++++++ + tests/testsuite.at | 1 + + 5 files changed, 50 insertions(+), 40 deletions(-) + create mode 100644 tests/extrac30.at + +diff --git a/src/extract.c b/src/extract.c +index 3878bc81..d7bac584 100644 +--- a/src/extract.c ++++ b/src/extract.c +@@ -1041,31 +1041,6 @@ extract_dir (char *file_name, int typeflag) + repair_delayed_set_stat (file_name, &st); + return 0; + } +- else if (old_files_option == NO_OVERWRITE_DIR_OLD_FILES) +- { +- /* Temporarily change the directory mode to a safe +- value, to be able to create files in it, should +- the need be. +- */ +- mode = safe_dir_mode (&st); +- status = fd_chmod(-1, file_name, mode, +- AT_SYMLINK_NOFOLLOW, DIRTYPE); +- if (status == 0) +- { +- /* Store the actual directory mode, to be restored +- later. +- */ +- current_stat_info.stat = st; +- current_mode = mode & ~ current_umask; +- current_mode_mask = MODE_RWX; +- atflag = AT_SYMLINK_NOFOLLOW; +- break; +- } +- else +- { +- chmod_error_details (file_name, mode); +- } +- } + break; + } + } +diff --git a/tests/Makefile.am b/tests/Makefile.am +index af80ec0b..b55305f5 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -111,6 +111,7 @@ TESTSUITE_AT = \ + extrac20.at\ + extrac21.at\ + extrac23.at\ ++ extrac30.at\ + filerem01.at\ + filerem02.at\ + dirrem01.at\ +diff --git a/tests/extrac23.at b/tests/extrac23.at +index 669d18b6..991f84cb 100644 +--- a/tests/extrac23.at ++++ b/tests/extrac23.at +@@ -15,15 +15,12 @@ + # + # You should have received a copy of the GNU General Public License + # along with this program. If not, see . +-AT_SETUP([--no-overwrite-dir]) ++AT_SETUP([--no-overwrite-dir on empty directory]) + AT_KEYWORDS([extract extrac23 no-overwrite-dir]) + + # Description: Implementation of the --no-overwrite-dir option was flawed in + # tar versions up to 1.32.90. This option is intended to preserve metadata + # of existing directories. In fact it worked only for non-empty directories. +-# Moreover, if the actual directory was owned by the user tar runs as and the +-# S_IWUSR bit was not set in its actual permissions, tar failed to create files +-# in it. + # + # Reported by: Michael Kaufmann + # References: <20200207112934.Horde.anXzYhAj2CHiwUrw5CuT0G-@webmail.michael-kaufmann.ch>, +@@ -38,21 +35,10 @@ chmod 777 dir + tar -xf a.tar --no-overwrite-dir + genfile --stat=mode.777 dir + +-# Test if temprorary permissions are set correctly to allow the owner +-# to write to the directory. +-genfile --file dir/file +-tar cf a.tar dir +-rm dir/file +-chmod 400 dir +-tar -xf a.tar --no-overwrite-dir +-genfile --stat=mode.777 dir +-chmod 700 dir + find dir + ], + [0], + [777 +-400 + dir +-dir/file + ]) + AT_CLEANUP +diff --git a/tests/extrac30.at b/tests/extrac30.at +new file mode 100644 +index 00000000..8c879c95 +--- /dev/null ++++ b/tests/extrac30.at +@@ -0,0 +1,47 @@ ++# Test suite for GNU tar. -*- Autotest -*- ++# Copyright 2020-2025 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 . ++AT_SETUP([--no-overwrite-dir on unwritable directory]) ++AT_KEYWORDS([extract extrac30 no-overwrite-dir]) ++ ++# Make sure that tar does not change permissions on directories if ++# --no-overwrite-dir tells it not to, not even temporarily. ++ ++AT_TAR_CHECK([ ++AT_UNPRIVILEGED_PREREQ ++ ++# Test that the user cannot write to a unwritable directory ++# if --no-overwrite-dir is used. ++mkdir dir ++chmod 755 dir ++genfile --file dir/file ++tar cf a.tar dir ++rm dir/file ++chmod 555 dir ++tar -xf a.tar --no-overwrite-dir ++genfile --stat=mode.777 dir ++chmod 755 dir ++find dir ++], ++[0], ++[555 ++dir ++], ++[tar: dir/file: Cannot open: Permission denied ++tar: Exiting with failure status due to previous errors ++]) ++AT_CLEANUP +diff --git a/tests/testsuite.at b/tests/testsuite.at +index 9bade4f2..3275d1c5 100644 +--- a/tests/testsuite.at ++++ b/tests/testsuite.at +@@ -310,6 +310,7 @@ m4_include([extrac19.at]) + m4_include([extrac20.at]) + m4_include([extrac21.at]) + m4_include([extrac23.at]) ++m4_include([extrac30.at]) + + m4_include([backup01.at]) + +-- +2.39.5 + diff --git a/tar-1.34-Warn-file-changed-as-we-read-it-less-often.patch b/tar-1.34-Warn-file-changed-as-we-read-it-less-often.patch new file mode 100644 index 0000000000000000000000000000000000000000..654d679dd31130fa118e0f10971be8b634983bc3 --- /dev/null +++ b/tar-1.34-Warn-file-changed-as-we-read-it-less-often.patch @@ -0,0 +1,164 @@ +From 7819e9ce26a6331f7a347c59cebfd5c6a8902ea3 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Thu, 15 Aug 2024 14:19:58 +0200 +Subject: [PATCH] =?UTF-8?q?Warn=20=E2=80=9Cfile=20changed=20as=20we=20read?= + =?UTF-8?q?=20it=E2=80=9D=20less=20often?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* src/create.c (dump_file0): Remove an fstatat call that is +unnecessary because the file wasn’t read so we can treat the first +fstatat as atomic. Warn “file changed” when the file’s size, +mtime, user ID, group ID, or mode changes, instead of when the +file’s size or ctime changes. Also, when such a change happens, +do not change exit status if --ignore-failed-read. Finally, don’t +attempt to change atime back if it didn’t change. +--- + doc/tar.texi | 10 ++++++---- + src/create.c | 54 ++++++++++++++++++++++++++++++++++++---------------- + 2 files changed, 44 insertions(+), 20 deletions(-) + +diff --git a/doc/tar.texi b/doc/tar.texi +index b66b163..dd5a272 100644 +--- a/doc/tar.texi ++++ b/doc/tar.texi +@@ -2854,7 +2854,7 @@ Ignore exit codes of subprocesses. @xref{Writing to an External Program}. + @opsummary{ignore-failed-read} + @item --ignore-failed-read + +-Do not exit unsuccessfully merely because an unreadable file was encountered. ++Do not exit unsuccessfully merely because reading failed. + @xref{Ignore Failed Read}. + + @opsummary{ignore-zeros} +@@ -4638,7 +4638,8 @@ Disable all warning messages. + @item file-changed + @samp{%s: file changed as we read it} + @item failed-read +-Suppresses warnings about unreadable files or directories. This ++Suppresses warnings about read failures, which can occur if files ++or directories are unreadable, or if they change while being read. This + keyword applies only if used together with the @option{--ignore-failed-read} + option. @xref{Ignore Failed Read}. + @end table +@@ -5761,11 +5762,12 @@ Disable SELinux context support. + @table @option + @item --ignore-failed-read + @opindex ignore-failed-read +-Do not exit with nonzero on unreadable files or directories. ++Do not exit with nonzero if there are mild problems while reading. + @end table + + This option has effect only during creation. It instructs tar to +-treat as mild conditions any missing or unreadable files (directories). ++treat as mild conditions any missing or unreadable files (directories), ++or files that change while reading. + Such failures don't affect the program exit code, and the + corresponding diagnostic messages are marked as warnings, not errors. + These warnings can be suppressed using the +diff --git a/src/create.c b/src/create.c +index e2816fc..2b3001d 100644 +--- a/src/create.c ++++ b/src/create.c +@@ -1650,8 +1650,6 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p) + { + union block *header; + char type; +- off_t original_size; +- struct timespec original_ctime; + off_t block_ordinal = -1; + int fd = 0; + bool is_dir; +@@ -1694,10 +1692,11 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p) + return; + } + +- st->archive_file_size = original_size = st->stat.st_size; ++ struct stat st1 = st->stat; ++ st->archive_file_size = st->stat.st_size; + st->atime = get_stat_atime (&st->stat); + st->mtime = get_stat_mtime (&st->stat); +- st->ctime = original_ctime = get_stat_ctime (&st->stat); ++ st->ctime = get_stat_ctime (&st->stat); + + #ifdef S_ISHIDDEN + if (S_ISHIDDEN (st->stat.st_mode)) +@@ -1747,7 +1746,7 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p) + if (is_dir || S_ISREG (st->stat.st_mode) || S_ISCTG (st->stat.st_mode)) + { + bool ok; +- struct stat final_stat; ++ struct stat st2; + + xattrs_acls_get (parentfd, name, st, 0, !is_dir); + xattrs_selinux_get (parentfd, name, st, fd); +@@ -1815,31 +1814,54 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p) + errno = - parentfd; + ok = false; + } +- else +- ok = fstatat (parentfd, name, &final_stat, fstatat_flags) == 0; + } + else +- ok = fstat (fd, &final_stat) == 0; ++ ok = fstat (fd, &st2) == 0; + + if (! ok) + file_removed_diag (p, top_level, stat_diag); + } + +- if (ok) ++ if (ok && fd) + { +- if ((timespec_cmp (get_stat_ctime (&final_stat), original_ctime) != 0 +- /* Original ctime will change if the file is a directory and +- --remove-files is given */ +- && !(remove_files_option && is_dir)) +- || original_size < final_stat.st_size) ++ /* Heuristically check whether the file is the same in all ++ attributes that tar cares about and can easily check. ++ Although the check is not perfect since it does not ++ consult file contents, it is typically good enough. ++ Do not check atime which is saved only to replace it later. ++ Do not check ctime where changes might be benign (e.g., ++ another process creates a hard link to the file). */ ++ ++ /* If the file's user ID, group ID or mode changed, tar may ++ have output the wrong info for the file. */ ++ ok &= st1.st_uid == st2.st_uid; ++ ok &= st1.st_gid == st2.st_gid; ++ ok &= st1.st_mode == st2.st_mode; ++ ++ /* Likewise for the file's mtime, but skip this check if it ++ is a directory possibly updated by --remove-files. */ ++ if (! (is_dir && remove_files_option)) ++ ok &= ! timespec_cmp (get_stat_mtime (&st1), ++ get_stat_mtime (&st2)); ++ ++ /* Likewise for the file's size, but skip this check if it ++ is a directory as tar does not output directory sizes. ++ Although dump_regular_file caught regular file shrinkage, ++ it shouldn't hurt to check for shrinkage again now; ++ plus, the file may have grown. */ ++ if (!is_dir) ++ ok &= st1.st_size == st2.st_size; ++ ++ if (!ok) + { + WARNOPT (WARN_FILE_CHANGED, + (0, 0, _("%s: file changed as we read it"), + quotearg_colon (p))); +- set_exit_status (TAREXIT_DIFFERS); ++ if (! ignore_failed_read_option) ++ set_exit_status (TAREXIT_DIFFERS); + } + else if (atime_preserve_option == replace_atime_preserve +- && fd && (is_dir || original_size != 0) ++ && timespec_cmp (st->atime, get_stat_atime (&st2)) != 0 + && set_file_atime (fd, parentfd, name, st->atime) != 0 + && errno != EROFS ) + utime_error (p); +-- +2.45.2 + diff --git a/tar.spec b/tar.spec index 1fcd80d78d97fc2e6e701dd9d20038c26c756eea..cd2c11a9b5f30a4998bd71e0c1d68f20404e76d6 100644 --- a/tar.spec +++ b/tar.spec @@ -1,4 +1,4 @@ -%define anolis_release .0.2 +%define anolis_release .0.1 %if %{?WITH_SELINUX:0}%{!?WITH_SELINUX:1} %global WITH_SELINUX 1 %endif @@ -7,7 +7,7 @@ Summary: A GNU file archiving program Name: tar Epoch: 2 Version: 1.30 -Release: 9%{anolis_release}%{?dist} +Release: 11%{anolis_release}%{?dist} License: GPLv3+ Group: Applications/Archiving URL: http://www.gnu.org/software/tar/ @@ -32,6 +32,15 @@ Patch17: tar-1.30-Fix-the-no-overwrite-dir-option # Remove the capabilities test, due to fails (BZ#2066320 and BZ#1926332) Patch18: tar-1.30-remove-capabs-test.patch Patch19: tar-1.30-CVE-2022-48303.patch +Patch20: tar-1.34-Warn-file-changed-as-we-read-it-less-often.patch +# inspired by upstream commit 64b43fdf70d82c39eb2ca900cd4f8e49b86c2020 +# "tests: fix race in dirrem01 and dirrem02" +# Patch20 for some reason exposes a race in the filerem01 test, +# use this to enforce the order where genfile wins the race +# and removes the test file before tar archives it. +Patch21: tar-1.30-filerem01.at-swap-actions.patch +# Source: https://cgit.git.savannah.gnu.org/cgit/tar.git/diff/?id=4e742fc8674064a9fa00d4483d06aca48d5b0463 +Patch22: tar-1.30-no-overwrite-dir-no-overwrite-even-temporarily.patch Patch100: tar-1.30-sw.patch # run "make check" by default @@ -149,11 +158,18 @@ fi %doc AUTHORS README THANKS NEWS ChangeLog %changelog -* Sat Jun 17 2023 wuxiat -1.30-9.0.2 +* Mon Sep 08 2025 Hangbo Fan - 2:1.30-11.0.1 +- Add doc sub package - add sw patch -* Thu May 25 2023 Hangbo Fan - 1.30-9.0.1 -- Add doc sub package +* Fri Aug 1 2025 Pavel Cahyna - 2:1.30-11 +- Backport fix for regression in the --no-overwrite-dir option fix (1.30-7) + Upstream commit 4e742fc8674064a9fa00d4483d06aca48d5b0463, discussed + in https://www.mail-archive.com/bug-tar@gnu.org/msg06445.html + +* Tue Jun 3 2025 Pavel Cahyna - 2:1.30-10 +- Warn “file changed as we read it” less often +- Add downstream patch to fix related failure in filerem01 test * Thu Feb 09 2023 Matej Mužila - 1.30-9 - Fix CVE-2022-48303