diff --git a/tar-1.34-CVE-2026-18477.patch b/tar-1.34-CVE-2026-18477.patch
new file mode 100644
index 0000000..7dcb86c
--- /dev/null
+++ b/tar-1.34-CVE-2026-18477.patch
@@ -0,0 +1,445 @@
+diff --git a/NEWS b/NEWS
+index 27553328..7679c015 100644
+--- a/NEWS
++++ b/NEWS
+@@ -13,6 +13,10 @@ version 1.35.90 (git)
+ ** When extracting, tar no longer follows symbolic links to targets
+ outside the working directory.
+
++** When extracting from an incremental dump, tar now strips leading '/'
++ from names of temporary directories specified by 'X' entries,
++ unless --absolute-names (-P) is used.
++
+ ** tar no longer fails merely if an extraction directory is unreadable
+ on Linux kernels.
+
+diff --git a/THANKS b/THANKS
+index b9e4ce54..f12d98c7 100644
+--- a/THANKS
++++ b/THANKS
+@@ -330,6 +330,7 @@ Manuel Munier Manuel.Munier@loria.fr
+ Marc Boucher marc@cam.org
+ Marc Ewing marc@redhat.com
+ Marcin Matuszewski marcin@frodo.nask.org.pl
++Marcin Wyczechowski mwyczechowski@afine.com
+ Marcus Daniels marcus@sysc.pdx.edu
+ Mark Bynum bynum@cennas.nhmfl.gov
+ Mark Clements mpc@mbsmm.com
+@@ -367,6 +368,7 @@ Michael Schmidt michael@muc.de
+ Michael Schwingen m.schwingen@stochastik.rwth-aachen.de
+ Michael Smolsky fnsiguc@astro.weizmann.ac.il
+ Michal Žejdl zejdl@suas.cz
++Michał Majchrowicz mmajchrowicz@afine.com
+ Mike Muuss mike@brl.mil
+ Mike Nolan nolan@lpl.arizona.edu
+ Mike Rogers mike@demon.net
+diff --git a/lib/Makefile.am b/lib/Makefile.am
+index 8fbe1c37..87b2f980 100644
+--- a/lib/Makefile.am
++++ b/lib/Makefile.am
+@@ -30,6 +30,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/gnu -I../ -I../gnu
+ AM_CFLAGS = $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS)
+
+ noinst_HEADERS = \
++ mkdtempat.h\
+ paxlib.h\
+ rmt.h\
+ system.h\
+@@ -38,6 +39,7 @@ noinst_HEADERS = \
+ xattr-at.h
+
+ libtar_a_SOURCES = \
++ mkdtempat.c\
+ paxerror.c paxexit-status.c paxlib.h paxnames.c \
+ rtapelib.c \
+ rmt.h \
+diff --git a/lib/mkdtempat.c b/lib/mkdtempat.c
+new file mode 100644
+index 00000000..e35b9bba
+--- /dev/null
++++ b/lib/mkdtempat.c
+@@ -0,0 +1,45 @@
++/* Copyright 2026 Free Software Foundation, Inc.
++
++ This program 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.
++
++ This program 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 .
++
++ Written by Paul Eggert. */
++
++#include
++
++#include "mkdtempat.h"
++
++#include
++
++#include
++#include
++
++static int
++try_dir (char *tmpl, void *flags)
++{
++ int *pdirfd = flags;
++ return mkdirat (*pdirfd, tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
++}
++
++/* Relative to the directory DIRFD if XTEMPLATE is relative,
++ generate a unique temporary directory from XTEMPLATE.
++ The last six characters of XTEMPLATE must be "XXXXXX";
++ replace them with a string that makes the generated directory unique.
++ Create the directory mode 700, and return its name.
++ On failure, return NULL and set errno. */
++char *
++mkdtempat (int dirfd, char *xtemplate)
++{
++ return (try_tempname_len (xtemplate, 0, &dirfd, try_dir, 6) < 0
++ ? NULL : xtemplate);
++}
+diff --git a/lib/mkdtempat.h b/lib/mkdtempat.h
+new file mode 100644
+index 00000000..03a18dc1
+--- /dev/null
++++ b/lib/mkdtempat.h
+@@ -0,0 +1 @@
++char *mkdtempat (int, char *);
+diff --git a/src/incremen.c b/src/incremen.c
+index 0a11acc9..c24a89c6 100644
+--- a/src/incremen.c
++++ b/src/incremen.c
+@@ -19,6 +19,7 @@
+
+ #include
+ #include
++#include
+ #include
+ #include "common.h"
+
+@@ -1653,13 +1654,16 @@ purge_directory (char const *directory_name)
+ if (*arc == 'X')
+ {
+ #define TEMP_DIR_TEMPLATE "tar.XXXXXX"
+- size_t len = strlen (arc + 1);
++ char *d = safer_name_suffix (arc + 1, false, absolute_names_option);
++ size_t len = strlen (d);
+ temp_stub = xrealloc (temp_stub, len + 1 + sizeof TEMP_DIR_TEMPLATE);
+- memcpy (temp_stub, arc + 1, len);
+- temp_stub[len] = '/';
+- memcpy (temp_stub + len + 1, TEMP_DIR_TEMPLATE,
++ char *copy_end = mempcpy (temp_stub, d, len);
++ *copy_end = '/';
++ memcpy (copy_end + !ISSLASH (copy_end[-1]), TEMP_DIR_TEMPLATE,
+ sizeof TEMP_DIR_TEMPLATE);
+- if (!mkdtemp (temp_stub))
++ struct fdbase f = fdbase (temp_stub);
++ if (f.fd == BADFD
++ || !mkdtempat (f.fd, temp_stub + (f.base - temp_stub)))
+ {
+ ERROR ((0, errno,
+ _("Cannot create temporary directory using template %s"),
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index f61bd8ac..a1c32ccd 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -206,6 +206,8 @@ TESTSUITE_AT = \
+ rename04.at\
+ rename05.at\
+ rename06.at\
++ rename08.at\
++ rename09.at\
+ remfiles01.at\
+ remfiles02.at\
+ remfiles03.at\
+diff --git a/tests/rename08.at b/tests/rename08.at
+new file mode 100644
+index 00000000..5452fb4f
+--- /dev/null
++++ b/tests/rename08.at
+@@ -0,0 +1,131 @@
++# Process this file with autom4te to create testsuite. -*- Autotest -*-
++
++# Test suite for GNU tar.
++# Copyright 2006-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 .
++
++# Description: Handling of cyclic renames in incremental archives.
++
++AT_SETUP([cyclic renames])
++AT_KEYWORDS([incremental rename rename08 cyclic-rename])
++
++AT_TAR_CHECK([
++AT_SORT_PREREQ
++
++mkdir foo
++genfile --file foo/file1
++genfile --file foo/file2
++
++mkdir foo/a
++genfile --file foo/a/filea
++
++mkdir foo/b
++genfile --file foo/b/fileb
++
++mkdir foo/c
++genfile --file foo/c/filec
++
++sleep 1
++
++echo "First dump"
++echo "First dump">&2
++tar -g incr -cf arch.1 -v foo 2>tmperr
++sort tmperr >&2
++
++# Shuffle directories:
++(cd foo
++mv a $$
++mv c a
++mv b c
++mv $$ b)
++
++echo "Second dump"
++echo "Second dump" >&2
++tar -g incr -cf arch.2 -v foo 2>tmperr
++sort tmperr >&2
++
++mkdir -p restoreparent/restore
++cd restoreparent
++tar xfg ../arch.1 /dev/null --warning=no-timestamp -C restore
++
++echo "Begin directory listing 1"
++( cd restore; find foo ) | sort
++echo "End directory listing 1"
++
++tar xfgv ../arch.2 /dev/null --warning=no-timestamp -C restore
++echo Begin directory listing 2
++( cd restore ; find foo ) | sort
++echo End directory listing 2
++],
++[0],
++[First dump
++foo/
++foo/a/
++foo/b/
++foo/c/
++foo/file1
++foo/file2
++foo/a/filea
++foo/b/fileb
++foo/c/filec
++Second dump
++foo/
++foo/a/
++foo/b/
++foo/c/
++Begin directory listing 1
++foo
++foo/a
++foo/a/filea
++foo/b
++foo/b/fileb
++foo/c
++foo/c/filec
++foo/file1
++foo/file2
++End directory listing 1
++foo/
++foo/a/
++foo/b/
++foo/c/
++Begin directory listing 2
++foo
++foo/a
++foo/a/filec
++foo/b
++foo/b/filea
++foo/c
++foo/c/fileb
++foo/file1
++foo/file2
++End directory listing 2
++],
++[First dump
++tar: foo/a: Directory is new
++tar: foo/b: Directory is new
++tar: foo/c: Directory is new
++tar: foo: Directory is new
++Second dump
++tar: foo/a: Directory has been renamed from 'foo/c'
++tar: foo/b: Directory has been renamed from 'foo/a'
++tar: foo/c: Directory has been renamed from 'foo/b'
++],
++[],[],[gnu, oldgnu, posix])
++
++AT_CLEANUP
++
++# End of rename03.at
+diff --git a/tests/rename09.at b/tests/rename09.at
+new file mode 100644
+index 00000000..8346ff0a
+--- /dev/null
++++ b/tests/rename09.at
+@@ -0,0 +1,129 @@
++# Process this file with autom4te to create testsuite. -*- Autotest -*-
++
++# Test suite for GNU tar.
++# Copyright 2006-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 .
++
++# Description: Handling of cyclic renames in incremental archives.
++
++AT_SETUP([cyclic renames])
++AT_KEYWORDS([incremental rename rename09 cyclic-rename])
++
++AT_TAR_CHECK([
++AT_SORT_PREREQ
++
++mkdir foo
++genfile --file foo/file1
++genfile --file foo/file2
++
++mkdir foo/a
++genfile --file foo/a/filea
++
++mkdir foo/b
++genfile --file foo/b/fileb
++
++mkdir foo/c
++genfile --file foo/c/filec
++
++sleep 1
++
++echo "First dump"
++echo "First dump">&2
++tar -g incr -cf arch.1 -v foo 2>tmperr
++sort tmperr >&2
++
++# Shuffle directories:
++(cd foo
++mv a $$
++mv c a
++mv b c
++mv $$ b)
++
++echo "Second dump"
++echo "Second dump" >&2
++tar -g incr -cf arch.2 -v foo 2>tmperr
++sort tmperr >&2
++
++tar xfg arch.1 /dev/null --warning=no-timestamp --one-top-level=restore
++
++echo "Begin directory listing 1"
++( cd restore; find foo ) | sort
++echo "End directory listing 1"
++
++tar xfgv arch.2 /dev/null --warning=no-timestamp --one-top-level=restore
++echo Begin directory listing 2
++( cd restore ; find foo ) | sort
++echo End directory listing 2
++],
++[0],
++[First dump
++foo/
++foo/a/
++foo/b/
++foo/c/
++foo/file1
++foo/file2
++foo/a/filea
++foo/b/fileb
++foo/c/filec
++Second dump
++foo/
++foo/a/
++foo/b/
++foo/c/
++Begin directory listing 1
++foo
++foo/a
++foo/a/filea
++foo/b
++foo/b/fileb
++foo/c
++foo/c/filec
++foo/file1
++foo/file2
++End directory listing 1
++foo/
++foo/a/
++foo/b/
++foo/c/
++Begin directory listing 2
++foo
++foo/a
++foo/a/filec
++foo/b
++foo/b/filea
++foo/c
++foo/c/fileb
++foo/file1
++foo/file2
++End directory listing 2
++],
++[First dump
++tar: foo/a: Directory is new
++tar: foo/b: Directory is new
++tar: foo/c: Directory is new
++tar: foo: Directory is new
++Second dump
++tar: foo/a: Directory has been renamed from 'foo/c'
++tar: foo/b: Directory has been renamed from 'foo/a'
++tar: foo/c: Directory has been renamed from 'foo/b'
++],
++[],[],[gnu, oldgnu, posix])
++
++AT_CLEANUP
++
++# End of rename03.at
+diff --git a/tests/testsuite.at b/tests/testsuite.at
+index fe5e7cd4..5f7b1fac 100644
+--- a/tests/testsuite.at
++++ b/tests/testsuite.at
+@@ -396,6 +396,8 @@ m4_include([rename03.at])
+ m4_include([rename04.at])
+ m4_include([rename05.at])
+ m4_include([rename06.at])
++m4_include([rename08.at])
++m4_include([rename09.at])
+ m4_include([chtype.at])
+
+ AT_BANNER([Ignore failing reads])
diff --git a/tar.spec b/tar.spec
index 2afb82e..58556f4 100644
--- a/tar.spec
+++ b/tar.spec
@@ -73,6 +73,11 @@ Patch26: tar-1.34-CVE-2026-5704.patch
# part of 941f62b2
# Also "by the way" fixes CVE-2026-18508.
Patch27: tar-1.34-fix-absolute-one-top-level.patch
+#Upstream commits
+# 0714d2f082104005a1c70ee6ec4175194943ea88
+# d479b2cc9160d9c2fb61afbc9ee70c2faadf80db
+# b17665b2c0548c77b6cd8d2d5b61e4c4fcc4f770
+Patch28: tar-1.34-CVE-2026-18477.patch
BuildRequires: make
BuildRequires: gcc