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

