Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package tar for openSUSE:Factory checked in at 2026-06-25 10:50:58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/tar (Old) and /work/SRC/openSUSE:Factory/.tar.new.2088 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "tar" Thu Jun 25 10:50:58 2026 rev:90 rq:1361195 version:1.35 Changes: -------- --- /work/SRC/openSUSE:Factory/tar/tar.changes 2026-05-10 16:47:50.383589372 +0200 +++ /work/SRC/openSUSE:Factory/.tar.new.2088/tar.changes 2026-06-25 10:54:55.104635532 +0200 @@ -1,0 +2,21 @@ +Mon Jun 22 16:07:49 UTC 2026 - Antonio Teixeira <[email protected]> + +- Fix CVE-2026-5704.patch causing errors when extracting certain archives + generated by rpm2archive which contain hard links +- Refresh fix-dereference.patch + +------------------------------------------------------------------- +Tue Jun 16 21:51:33 UTC 2026 - Antonio Teixeira <[email protected]> + +- Fix tar changing dir permissions temporarily even when using --no-overwrite-dir + * no-overwrite-dir-fix.patch +- Fix CVE-2026-5704, crafted archives can be used to to hide file injection + (bsc#1261900) + * CVE-2026-5704.patch +- Fix --dereference/-h not working properly after CVE-2025-45582 fix (bsc#1265450) + * fix-dereference.patch +- Fix extraction failure for paths like "a/./b" caused by the gnulib openat2 + implementation (bsc#1267189) + * openat2-fix-dotlike-failure.patch + +------------------------------------------------------------------- New: ---- CVE-2026-5704.patch fix-dereference.patch no-overwrite-dir-fix.patch openat2-fix-dotlike-failure.patch ----------(New B)---------- New: - Fix CVE-2026-5704.patch causing errors when extracting certain archives generated by rpm2archive which contain hard links New: generated by rpm2archive which contain hard links - Refresh fix-dereference.patch New:- Fix tar changing dir permissions temporarily even when using --no-overwrite-dir * no-overwrite-dir-fix.patch - Fix CVE-2026-5704, crafted archives can be used to to hide file injection New: implementation (bsc#1267189) * openat2-fix-dotlike-failure.patch ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ tar.spec ++++++ --- /var/tmp/diff_new_pack.pA5qee/_old 2026-06-25 10:54:56.000666533 +0200 +++ /var/tmp/diff_new_pack.pA5qee/_new 2026-06-25 10:54:56.000666533 +0200 @@ -54,6 +54,18 @@ Patch17: add_forgotten-tests.patch Patch18: tar-fix-deletion-from-archive.patch Patch19: CVE-2025-45582.patch +# PATCH-FIX-UPSTREAM [email protected] +# Fix tar changing dir permissions temporarily even when using --no-overwrite-dir +Patch20: no-overwrite-dir-fix.patch +# PATCH-FIX-UPSTREAM [email protected] bsc#1261900 +# CVE-2026-5704 - crafted archives can be used to to hide file injection +Patch21: CVE-2026-5704.patch +# PATCH-FIX-UPSTREAM [email protected] bsc#1265450 +# Fix --dereference/-h not working properly after CVE-2025-45582 fix +Patch22: fix-dereference.patch +# PATCH-FIX-UPSTREAM [email protected] bsc#1267189 +# Fix extraction failure for paths like "a/./b" caused by the gnulib openat2 implementation +Patch23: openat2-fix-dotlike-failure.patch BuildRequires: automake >= 1.15 BuildRequires: libacl-devel BuildRequires: libselinux-devel ++++++ CVE-2026-5704.patch ++++++ >From b8d8a61b25588caca4efaf9bdd2e3f1a49da77e3 Mon Sep 17 00:00:00 2001 From: Paul Eggert <[email protected]> Date: Sun, 22 Mar 2026 12:19:40 -0700 Subject: [PATCH] Fix more -t/-x discrepancies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem reported by Guillermo de Angel in: https://lists.gnu.org/r/bug-tar/2026-03/msg00007.html * THANKS: Add him, and sort. * src/extract.c (extract_dir, extract_file): * src/incremen.c (purge_directory): Do not call skip_member, as the caller now does that, and does it more reliably. * src/extract.c (extract_file): Mark file as skipped when we’ve read it. (extract_archive): Always call skip_member after extracting, as it suppresses the skip as needed. * src/incremen.c (try_purge_directory): Remove; no longer needed. Move internals to purge_directory. * src/list.c (read_header): Do not treat LNKTYPE header as having size zero, as it can be nonzero (e.g., ‘pax -o linkdata’). Set info->skipped field according to how the header was read. (member_is_dir): Remove; no longer needed. (skim_member): Skip directory data too, unless it’s already been skipped (i.e., read). * tests/extrac32.at: New file. * tests/Makefile.am (TESTSUITE_AT): * tests/testsuite.at: Add it. * tests/skipdir.at (skip directory members): Fix test to match the correct behavior. This fixes a bug introduced in commit b009124ffde415515081db844d7a104e1d1c6c58 dated 2025-05-12 17:17:21 +0300. --- THANKS | 30 +++++++++++++++-------------- src/extract.c | 23 ++++++---------------- src/incremen.c | 22 +++++++-------------- src/list.c | 48 +++++++++++++++------------------------------- tests/Makefile.am | 1 + tests/extrac32.at | 47 +++++++++++++++++++++++++++++++++++++++++++++ tests/skipdir.at | 6 +----- tests/testsuite.at | 1 + 8 files changed, 94 insertions(+), 84 deletions(-) create mode 100644 tests/extrac32.at Index: b/THANKS =================================================================== --- a/THANKS +++ b/THANKS @@ -198,6 +198,7 @@ Greg Hudson [email protected] Greg Maples [email protected] Greg McGary [email protected] Greg Schafer [email protected] +Guillermo de Angel [email protected] Göran Uddeborg [email protected] Gürkan Karaman [email protected] Hans Guerth [email protected] Index: b/src/extract.c =================================================================== --- a/src/extract.c +++ b/src/extract.c @@ -1081,8 +1081,6 @@ extract_dir (char *file_name, int typefl if (incremental_option) /* Read the entry and delete files that aren't listed in the archive. */ purge_directory (file_name); - else if (typeflag == GNUTYPE_DUMPDIR) - skip_member (); mode = safe_dir_mode (¤t_stat_info.stat); @@ -1262,10 +1260,7 @@ extract_file (char *file_name, int typef { fd = sys_exec_command (file_name, 'f', ¤t_stat_info); if (fd < 0) - { - skip_member (); - return 0; - } + return 0; } else { @@ -1285,7 +1280,6 @@ extract_file (char *file_name, int typef int recover = maybe_recoverable (file_name, true, &interdir_made); if (recover != RECOVER_OK) { - skip_member (); if (recover == RECOVER_SKIP) return 0; open_error (file_name); @@ -1333,6 +1327,7 @@ extract_file (char *file_name, int typef } skim_file (size, false); + current_stat_info.skipped = true; mv_end (); @@ -1865,15 +1860,9 @@ extract_archive (void) typeflag = sparse_member_p (¤t_stat_info) ? GNUTYPE_SPARSE : current_header->header.typeflag; - if (prepare_to_extract (current_stat_info.file_name, typeflag, &fun)) - { - if (fun (current_stat_info.file_name, typeflag) == 0) - return; - } - else - skip_member (); - - if (backup_option) + bool ok = prepare_to_extract (current_stat_info.file_name, typeflag, &fun) && ( fun (current_stat_info.file_name, typeflag) == 0); + skip_member (); + if (!ok && backup_option) undo_last_backup (); } Index: b/src/incremen.c =================================================================== --- a/src/incremen.c +++ b/src/incremen.c @@ -1625,8 +1625,8 @@ dumpdir_ok (char *dumpdir) /* Examine the directories under directory_name and delete any files that were not there at the time of the back-up. */ -static bool -try_purge_directory (char const *directory_name) +void +purge_directory (char const *directory_name) { char *current_dir; char *cur, *arc, *p; @@ -1634,18 +1634,18 @@ try_purge_directory (char const *directo struct dumpdir *dump; if (!is_dumpdir (¤t_stat_info)) - return false; + return; current_dir = tar_savedir (directory_name, 0); if (!current_dir) /* The directory doesn't exist now. It'll be created. In any case, we don't have to delete any files out of it. */ - return false; + return; /* Verify if dump directory is sane */ if (!dumpdir_ok (current_stat_info.dumpdir)) - return false; + return; /* Process renames */ for (arc = current_stat_info.dumpdir; *arc; arc += strlen (arc) + 1) @@ -1666,7 +1666,7 @@ try_purge_directory (char const *directo quote (temp_stub))); free (temp_stub); free (current_dir); - return false; + return; } } else if (*arc == 'R') @@ -1700,7 +1700,7 @@ try_purge_directory (char const *directo free (current_dir); /* FIXME: Make sure purge_directory(dst) will return immediately */ - return false; + return; } } } @@ -1758,14 +1758,6 @@ try_purge_directory (char const *directo dumpdir_free (dump); free (current_dir); - return true; -} - -void -purge_directory (char const *directory_name) -{ - if (!try_purge_directory (directory_name)) - skip_member (); } void Index: b/src/list.c =================================================================== --- a/src/list.c +++ b/src/list.c @@ -448,20 +448,15 @@ read_header (union block **return_block, if ((status = tar_checksum (header, false)) != HEADER_SUCCESS) break; - /* Good block. Decode file size and return. */ - - if (header->header.typeflag == LNKTYPE) - info->stat.st_size = 0; /* links 0 size on tape */ - else + info->stat.st_size = OFF_FROM_HEADER (header->header.size); + if (info->stat.st_size < 0) { - info->stat.st_size = OFF_FROM_HEADER (header->header.size); - if (info->stat.st_size < 0) - { - status = HEADER_FAILURE; - break; - } + status = HEADER_FAILURE; + break; } + info->skipped = false; + if (header->header.typeflag == GNUTYPE_LONGNAME || header->header.typeflag == GNUTYPE_LONGLINK || header->header.typeflag == XHDTYPE @@ -524,11 +519,15 @@ read_header (union block **return_block, } *bp = '\0'; + info->skipped = true; } else if (header->header.typeflag == XHDTYPE || header->header.typeflag == SOLARIS_XHDTYPE) - xheader_read (&info->xhdr, header, - OFF_FROM_HEADER (header->header.size)); + { + xheader_read (&info->xhdr, header, + OFF_FROM_HEADER (header->header.size)); + info->skipped = true; + } else if (header->header.typeflag == XGLTYPE) { struct xheader xhdr; @@ -542,6 +541,7 @@ read_header (union block **return_block, OFF_FROM_HEADER (header->header.size)); xheader_decode_global (&xhdr); xheader_destroy (&xhdr); + info->skipped = true; if (mode == read_header_x_global) { status = HEADER_SUCCESS_EXTENDED; @@ -1471,10 +1471,11 @@ skim_member (bool must_copy) if (current_stat_info.is_sparse) sparse_skim_file (¤t_stat_info, must_copy); - else if (save_typeflag != DIRTYPE) + else skim_file (current_stat_info.stat.st_size, must_copy); mv_end (); + current_stat_info.skipped = true; } } Index: b/tests/Makefile.am =================================================================== --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -127,6 +127,7 @@ TESTSUITE_AT = \ extrac25.at\ extrac30.at\ extrac31.at\ + extrac32.at\ filerem01.at\ filerem02.at\ dirrem01.at\ Index: b/tests/extrac32.at =================================================================== --- /dev/null +++ b/tests/extrac32.at @@ -0,0 +1,47 @@ +# Check for file injection bug with symlinks. -*- Autotest -*- + +# Copyright 2026 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/>. + +# Thanks to Guillermo de Angel for the bug report and test cases; see: +# https://lists.gnu.org/r/bug-tar/2026-03/msg00007.html + +AT_SETUP([skip file injection]) +AT_KEYWORDS([injection]) +AT_DATA([archive.in], +[/Td6WFoAAATm1rRGBMDbAYAcIQEcAAAAAAAAACYr+9LgDf8A010AMZhKvfVdtHe4Rxjj7M03ek97 +UgeKfJ0ORqYg0XDFntWxdTH4PYrTOo9CoqBrnTM2NcwFBrRVr7aFwdd56vddyAw2QGDjxgNexDU3 +ImTi/+z8ZOLMi/+AybdEpd5aA/M9Maa+8tQ84bySzSAwrmxMWJJ6W9IKvsqfiRa3TrD51v44PZU/ +KLVKpocS56n/O3g+b+hiZwaysR0eLO+tiU8FB/e3PEq3vTtDFVi/YfZMieBWSzomSX9eF13K1yPY +UuWgp7VokXqduL0YGNVV40MTPG9oAAAApD6mpajengIAAfcBgBwAAOM4xw6xxGf7AgAAAAAEWVo= +]) +AT_CHECK([base64 --help >/dev/null 2>&1 || AT_SKIP_TEST +xz --help >/dev/null 2>&1 || AT_SKIP_TEST +base64 -d < archive.in | xz -c -d > archive.tar +]) +cp archive.tar /tmp +AT_CHECK([tar tf archive.tar], +[0], +[carrier_entry +marker.txt +]) +AT_CHECK([tar xvf archive.tar], +[0], +[carrier_entry +marker.txt +]) +AT_CLEANUP Index: b/tests/testsuite.at =================================================================== --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -353,6 +353,7 @@ m4_include([extrac24.at]) m4_include([extrac25.at]) m4_include([extrac30.at]) m4_include([extrac31.at]) +m4_include([extrac32.at]) m4_include([backup01.at]) commit 67981bbb1587803bb1e029393d2228492cef8c4f Author: Paul Eggert <[email protected]> Date: Sat Jun 20 00:28:17 2026 -0700 tar: ignore nonzero sizes in hard links etc Problem reported by Antonio Teixeira. * src/list.c (read_header): When POSIX says a size field must be zero or does not represent a data count, treat it as zero. * tests/extrac32.at: Update to match new behavior. We now treat hard link sizes as zero even when the size fields are nonzero, and this means the “injected” file is treated as valid regardless of whether we list or extract. * tests/extrac34.at: New test. * tests/Makefile.am (TESTSUITE_AT), tests/testsuite.at: Add it. diff --git a/src/list.c b/src/list.c index 5ab6de42..1c992cf4 100644 --- a/src/list.c +++ b/src/list.c @@ -535,6 +535,22 @@ read_header (union block **return_block, struct tar_stat_info *info, struct posix_header const *h = &header->header; char namebuf[sizeof h->prefix + 1 + NAME_FIELD_SIZE + 1]; + switch (h->typeflag) + { + /* For these file types, although POSIX does not specify the + meaning of the size, it does say there should be no data, + so treat the size as zero. */ + case BLKTYPE: case CHRTYPE: case FIFOTYPE: + + /* For these file types, POSIX requires that the size be zero. + Be generous and accept any size as zero, as some + nonconforming programs generate nonzero size fields along + with no data. */ + case LNKTYPE: case SYMTYPE: + + info->stat.st_size = 0; + } + free (recent_long_name); if (next_long_name) diff --git a/tests/Makefile.am b/tests/Makefile.am index 103c6de7..4f666b09 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -143,6 +143,7 @@ TESTSUITE_AT = \ extrac30.at\ extrac31.at\ extrac32.at\ + extrac34.at\ filerem01.at\ filerem02.at\ dirrem01.at\ diff --git a/tests/extrac32.at b/tests/extrac32.at index d3505fdb..af40916d 100644 --- a/tests/extrac32.at +++ b/tests/extrac32.at @@ -36,11 +36,13 @@ base64 -d < archive.in | xz -c -d > archive.tar AT_CHECK([tar tf archive.tar], [0], [carrier_entry +injected.txt marker.txt ]) AT_CHECK([tar xvf archive.tar], [0], [carrier_entry +injected.txt marker.txt ]) AT_CLEANUP diff --git a/tests/extrac34.at b/tests/extrac34.at new file mode 100644 index 00000000..1cedb463 --- /dev/null +++ b/tests/extrac34.at @@ -0,0 +1,40 @@ +# Check hard link with nonzero size field in tarball. -*- Autotest -*- + +# Copyright 2026 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/>. + +# Check extracting from a nonconforming tarball that has +# a hard link with nonzero size. + +AT_SETUP([hard link with a nonzero size field]) +AT_KEYWORDS([extract extrac34 hard link]) +AT_DATA([archive.in], +[/Td6WFoAAATm1rRGBMBwgFAhARwAAAAAAAAAAAbKrCjgJ/8AaF0AMIAzUBhoiawFdYeRen4lxlj0 +QWRLpUM+28ArRsXVY5bGv4H5kijsqiJ4Z9YIVhZd01+IppF+AkltS60aB8fuUW35Tp/3XzUx9Mq2 +4ypJFzvcgHXsSIvc9L+mmTDuHzhvJQ/oe7ya8QAASbOfD7CgZcIAAYwBgFAAAEWxohaxxGf7AgAA +AAAEWVo= +]) +AT_CHECK([base64 --help >/dev/null 2>&1 || AT_SKIP_TEST +xz --help >/dev/null 2>&1 || AT_SKIP_TEST +base64 -d < archive.in | xz -c -d > archive.tar +]) +AT_CHECK([mkdir dir +]) +AT_CHECK([tar -C dir -xf archive.tar || exit 1 +cmp dir/a dir/b +]) +AT_CLEANUP diff --git a/tests/testsuite.at b/tests/testsuite.at index 70d36a5a..ab30c2ab 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -360,6 +360,7 @@ m4_include([extrac30.at]) m4_include([extrac30.at]) m4_include([extrac31.at]) m4_include([extrac32.at]) +m4_include([extrac34.at]) m4_include([backup01.at]) ++++++ fix-dereference.patch ++++++ commit 145a671e8ad0f2443e253ea4cc95b676ed7a2847 Author: Sergey Poznyakoff <[email protected]> Date: Thu Jun 11 16:33:15 2026 +0300 Fix extracting over symlinks with --dereference Extraction over symlink to a directory was broken in 75b03fdff4. See https://savannah.gnu.org/bugs/index.php?68368 * src/tar.c (decode_options): Don't enable RESOLVE_BENEATH mode if --dereference is given. * tests/extrac33.at: New test. * tests/Makefile.am: Add new test. * tests/testsuite.at: Likewise. * tests/extrac13.at: Add a keyword. * tests/extrac31.at: Remove --absolute-names keyword: that option is never used in the testcase. Add CVE-2025-45582 keyword instead. Index: b/src/tar.c =================================================================== --- a/src/tar.c +++ b/src/tar.c @@ -2633,7 +2633,7 @@ decode_options (int argc, char **argv) #endif open_searchdir_how.flags = (search_flags | nofollow_flag | O_BINARY | O_CLOEXEC | O_DIRECTORY); - if (!absolute_names_option + if (!absolute_names_option && !dereference_option && (subcommand_option == EXTRACT_SUBCOMMAND || subcommand_option == DIFF_SUBCOMMAND)) open_searchdir_how.resolve = RESOLVE_BENEATH; Index: b/tests/Makefile.am =================================================================== --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -128,6 +128,7 @@ TESTSUITE_AT = \ extrac30.at\ extrac31.at\ extrac32.at\ + extrac33.at\ extrac34.at\ filerem01.at\ filerem02.at\ Index: b/tests/extrac13.at =================================================================== --- a/tests/extrac13.at +++ b/tests/extrac13.at @@ -24,7 +24,7 @@ # unless --dereference is specified. AT_SETUP([extract over symlinks]) -AT_KEYWORDS([extract extrac13 chdir]) +AT_KEYWORDS([extract extrac13 chdir --dereference]) AT_TAR_CHECK([ mkdir src dst1 dst2 dst3 Index: b/tests/extrac31.at =================================================================== --- a/tests/extrac31.at +++ b/tests/extrac31.at @@ -17,8 +17,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. AT_SETUP([extracting untrusted incremental]) -AT_KEYWORDS([extract extrac31 --absolute-names]) - +AT_KEYWORDS([extract extrac31 CVE-2025-45582]) AT_TAR_CHECK([ Index: b/tests/extrac33.at =================================================================== --- /dev/null +++ b/tests/extrac33.at @@ -0,0 +1,53 @@ +# Test suite for GNU tar. -*- Autotest -*- +# Copyright 2026 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/>. + +# Description: Fixing CVE-2025-45582 (commit 75b03fdff4) broke some +# legitimate cases of extracting over symlinks with the --dereference +# option. Check if that is fixed. +# +# References: https://savannah.gnu.org/bugs/index.php?68368 + +AT_SETUP([extract over symlink to dir with --dereference]) +AT_KEYWORDS([extract extrac33 CVE-2025-45582 --dereference]) +AT_DATA([archive.in], +[/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4Cf/AJxdABcLvBx9AZXAHUpGnBzE/y67neFgHitlwSWw +/oOsdf1GACIE/0RnS0Lp6Mj1RyfaFcxOxcWz61KEu+VeJMMAUhYEcMyGrz191zPA4rOoVcIqYEm0 +B9Jiq66xT/4F6gUOeitk5fqE+uMdHKK7QTaty/dnoxtba+McJh/dXP2TUStl0xetvrnvCE1/2tKZ +grqe/9/HpysFqZnu5sskAABO7ZNxp1eWNgABuAGAUAAA/vRJibHEZ/sCAAAAAARZWg== +]) +AT_CHECK([base64 --help >/dev/null 2>&1 || AT_SKIP_TEST +xz --help >/dev/null 2>&1 || AT_SKIP_TEST +base64 -d < archive.in | xz -c -d > archive.tar +]) +AT_CHECK([mkdir dir dir2 hdir +cd dir +ln -sf ../dir2 . +cd ../hdir +ln -sf ../dir2 . +]) +AT_CHECK([tar -C dir -xf archive.tar || exit 1 +test -d dir/dir2 +]) +AT_CHECK([tar -C hdir -hxf archive.tar || exit 1 +test -h hdir/dir2 || exit 2 +ls dir2 +], +[0], +[file2 +]) +AT_CLEANUP Index: b/tests/testsuite.at =================================================================== --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -354,6 +354,7 @@ m4_include([extrac25.at]) m4_include([extrac30.at]) m4_include([extrac31.at]) m4_include([extrac32.at]) +m4_include([extrac33.at]) m4_include([extrac34.at]) m4_include([backup01.at]) ++++++ no-overwrite-dir-fix.patch ++++++ commit 4e742fc8674064a9fa00d4483d06aca48d5b0463 Author: Paul Eggert <[email protected]> Date: Sat Jul 26 21:41:23 2025 -0700 --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. Index: b/src/extract.c =================================================================== --- a/src/extract.c +++ b/src/extract.c @@ -1126,31 +1126,6 @@ extract_dir (char *file_name, int typefl 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; } } Index: b/tests/Makefile.am =================================================================== --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -125,6 +125,7 @@ TESTSUITE_AT = \ extrac23.at\ extrac24.at\ extrac25.at\ + extrac30.at\ extrac31.at\ filerem01.at\ filerem02.at\ Index: b/tests/extrac23.at =================================================================== --- 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 <[email protected]> # References: <20200207112934.horde.anxzyhaj2chiwurw5cut...@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 temporary 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 Index: b/tests/extrac30.at =================================================================== --- /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 Index: b/tests/testsuite.at =================================================================== --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -351,6 +351,7 @@ m4_include([extrac22.at]) m4_include([extrac23.at]) m4_include([extrac24.at]) m4_include([extrac25.at]) +m4_include([extrac30.at]) m4_include([extrac31.at]) m4_include([backup01.at]) ++++++ openat2-fix-dotlike-failure.patch ++++++ >From 50d7bb88f547aff37e6279bdc84a7602e1dd3533 Mon Sep 17 00:00:00 2001 From: Paul Eggert <[email protected]> Date: Wed, 17 Jun 2026 00:19:35 -0700 Subject: openat2: fix bug with trailing "/./" Problem reported by Kinan Al-Falakh in: https://lists.gnu.org/r/bug-gnulib/2026-06/msg00070.html * lib/openat2.c (do_openat2): When opening a dotlike component at file name end, also set the G and H indexes appropriately for ".". This matters if the file name ends in something like "/./" so the last component "." is not at file name end. * tests/test-openat2.c (do_test_resolve): Test for the bug. --- ChangeLog | 11 +++++++++++ lib/openat2.c | 3 ++- tests/test-openat2.c | 11 +++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/gnu/openat2.c b/gnu/openat2.c index 2be62c921c..8c722427f7 100644 --- a/gnu/openat2.c +++ b/gnu/openat2.c @@ -320,8 +320,9 @@ do_openat2 (int *fd, char const *filename, { /* This is empty or the last component, and acts like ".". Use "." regardless of whether it was "" or "." or "..". */ - f = sizeof "."; + f = g = sizeof "."; e[-f] = '.'; + h = 1; } /* Open the current component, as either an internal directory or -- cgit v1.2.3
