Compare commits

...

No commits in common. "c8" and "c8-beta" have entirely different histories.
c8 ... c8-beta

4 changed files with 1 additions and 380 deletions

View File

@ -1,15 +0,0 @@
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],

View File

@ -1,182 +0,0 @@
From d4f7fd373e79dddd7f411589808d80ac8032e6e3 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
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 <http://www.gnu.org/licenses/>.
-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 <mail@michael-kaufmann.ch>
# 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 <http://www.gnu.org/licenses/>.
+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

View File

@ -1,164 +0,0 @@
From 7819e9ce26a6331f7a347c59cebfd5c6a8902ea3 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
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 wasnt read so we can treat the first
fstatat as atomic. Warn “file changed” when the files size,
mtime, user ID, group ID, or mode changes, instead of when the
files size or ctime changes. Also, when such a change happens,
do not change exit status if --ignore-failed-read. Finally, dont
attempt to change atime back if it didnt 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

View File

@ -6,7 +6,7 @@ Summary: A GNU file archiving program
Name: tar
Epoch: 2
Version: 1.30
Release: 11%{?dist}
Release: 9%{?dist}
License: GPLv3+
Group: Applications/Archiving
URL: http://www.gnu.org/software/tar/
@ -31,15 +31,6 @@ 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
# run "make check" by default
%bcond_without check
@ -146,15 +137,6 @@ fi
%{_infodir}/tar.info*
%changelog
* Fri Aug 1 2025 Pavel Cahyna <pcahyna@redhat.com> - 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 <pcahyna@redhat.com> - 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 <mmuzila@redhat.com> - 1.30-9
- Fix CVE-2022-48303
- Resolves: CVE-2022-48303