Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:patool
User: [email protected]
Usertags: pu

Dear stable release managers, please consider patool/4.0.0-1+deb13u1
for trixie.

[ Reason ]
CVE-2026-29509 reported against patool.


[ Impact ]
CVE-2026-29509 is a path traversal vulnerability. Exposing users to
such vulnerability is not trivial. 

[ Tests ]
Package contain extensive testsuite which ran successfully.

[ Risks ]
The security fix patch backported from the upstream version 4.0.5 and
merged with minimal fuzz.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

--abhijith
diff -Nru patool-4.0.0/debian/changelog patool-4.0.0/debian/changelog
--- patool-4.0.0/debian/changelog       2025-03-21 11:12:05.000000000 +0530
+++ patool-4.0.0/debian/changelog       2026-07-07 11:38:59.000000000 +0530
@@ -1,3 +1,10 @@
+patool (4.0.0-1+deb13u1) trixie; urgency=medium
+
+  * Fix CVE-2026-29509: a path traversal vulnerability in the
+    safe_extract() function. d/patches/CVE-2026-29509.patch
+
+ -- Abhijith PA <[email protected]>  Tue, 07 Jul 2026 11:38:59 +0530
+
 patool (4.0.0-1) unstable; urgency=medium
 
   * New upstream release.
diff -Nru patool-4.0.0/debian/patches/CVE-2026-29509.patch 
patool-4.0.0/debian/patches/CVE-2026-29509.patch
--- patool-4.0.0/debian/patches/CVE-2026-29509.patch    1970-01-01 
05:30:00.000000000 +0530
+++ patool-4.0.0/debian/patches/CVE-2026-29509.patch    2026-07-07 
11:38:39.000000000 +0530
@@ -0,0 +1,78 @@
+From e5660a4b0a4b2c4202889bf8700a375cbb6ee78b Mon Sep 17 00:00:00 2001
+From: Bastian Kleineidam <[email protected]>
+Date: Mon, 18 May 2026 10:54:58 +0200
+Subject: [PATCH] Fix generation of files and directories outside of the
+ extraction dir
+
+---
+ patoolib/fileutil.py            | 10 ++++++++++
+ patoolib/programs/py_tarfile.py | 12 ++----------
+ tests/test_fileutil.py          |  9 +++++++++
+ 4 files changed, 26 insertions(+), 12 deletions(-)
+
+--- a/patoolib/fileutil.py
++++ b/patoolib/fileutil.py
+@@ -193,3 +193,13 @@ def make_user_readable(directory: str) -
+             make_file_readable(os.path.join(root, filename))
+         for dirname in dirs:
+             make_dir_readable(os.path.join(root, dirname))
++
++
++def is_within_directory(directory, target):
++    """Check that given target path is a subdirectory inside the directory."""
++    abs_directory = os.path.realpath(os.path.abspath(directory))
++    abs_target = os.path.realpath(os.path.abspath(target))
++    try:
++        return os.path.commonpath([abs_directory, abs_target]) == 
abs_directory
++    except ValueError:
++        return False
+--- a/patoolib/programs/py_tarfile.py
++++ b/patoolib/programs/py_tarfile.py
+@@ -14,7 +14,7 @@
+ # along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ """Archive commands for the tarfile Python module."""
+ 
+-from .. import util
++from .. import util, fileutil
+ import os
+ import sys
+ import tarfile
+@@ -46,14 +46,6 @@ def extract_tar(archive, compression, cm
+     return None
+ 
+ 
+-def is_within_directory(directory, target):
+-    """Check that given target path is a subdirectory inside the directory."""
+-    abs_directory = os.path.abspath(directory)
+-    abs_target = os.path.abspath(target)
+-    prefix = os.path.commonprefix([abs_directory, abs_target])
+-    return prefix == abs_directory
+-
+-
+ def safe_extract(tfile, path):
+     """Helper function to ensure that TAR members will be extracted inside
+     the given path.
+@@ -63,7 +55,7 @@ def safe_extract(tfile, path):
+     bad_members = []
+     for member in tfile.getmembers():
+         member_path = os.path.join(path, member.name)
+-        if is_within_directory(path, member_path):
++        if fileutil.is_within_directory(path, member_path):
+             safe_members.append(member)
+         else:
+             bad_members.append(member)
+--- a/tests/test_fileutil.py
++++ b/tests/test_fileutil.py
+@@ -63,3 +63,12 @@ class UtilTest(unittest.TestCase):
+             f.write("42")
+         fileutil.rmtree(existing_dir)
+         self.assertFalse(os.path.exists(existing_dir))
++
++    def test_is_within_directory(self):
++        """Test is_within_directory()"""
++        curdir = os.getcwd()
++        dest = os.path.join(curdir, "outputdir")
++        member = os.path.join("outputdir2", "test.txt")
++        self.assertFalse(fileutil.is_within_directory(dest, member))
++        member = os.path.join("outputdir", "test.txt")
++        self.assertTrue(fileutil.is_within_directory(dest, member))
diff -Nru patool-4.0.0/debian/patches/series patool-4.0.0/debian/patches/series
--- patool-4.0.0/debian/patches/series  2024-11-12 14:04:06.000000000 +0530
+++ patool-4.0.0/debian/patches/series  2026-07-07 11:38:31.000000000 +0530
@@ -0,0 +1 @@
+CVE-2026-29509.patch

Reply via email to