From ad73b5244b74a4558ca15a95ee4de09a8915e5e7 Mon Sep 17 00:00:00 2001 From: Pavel Cahyna Date: Fri, 1 Aug 2025 17:09:07 +0200 Subject: [PATCH] Backport fix of --no-overwrite-dir Upstream commit 4e742fc8674064a9fa00d4483d06aca48d5b0463 Resolves: RHEL-57019 --- ...te-dir-no-overwrite-even-temporarily.patch | 182 ++++++++++++++++++ tar.spec | 2 + 2 files changed, 184 insertions(+) create mode 100644 tar-1.30-no-overwrite-dir-no-overwrite-even-temporarily.patch 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 0000000..a6de88c --- /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.spec b/tar.spec index 766f403..9346079 100644 --- a/tar.spec +++ b/tar.spec @@ -38,6 +38,8 @@ Patch20: tar-1.34-Warn-file-changed-as-we-read-it-less-often.patch # 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