]> git.ipfire.org Git - thirdparty/samba.git/commit
pytest: safe_tarfile: accept NotADirectoryError as bad path rejection
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Fri, 22 Aug 2025 03:24:34 +0000 (15:24 +1200)
committerDouglas Bagnall <dbagnall@samba.org>
Tue, 26 Aug 2025 22:42:39 +0000 (22:42 +0000)
commit7a5b22e4221ea2a0960a26cf79339168f0899d0c
treec099f7f58a846e4894a5897092481f4ae8631ef9
parent8969e48023eaf073eb1d4e9122afe4ac98f414a7
pytest: safe_tarfile: accept NotADirectoryError as bad path rejection

After recent upstream Python fixes for various path escape and symlink
CVEs in tarfile, in particular this commit:

  commit 3612d8f51741b11f36f8fb0494d79086bac9390a
  Author: Łukasz Langa <lukasz@langa.pl>
  Date:   Tue Jun 3 12:42:11 2025 +0200

  gh-135034: Normalize link targets in tarfile, add `os.path.realpath(strict='allow_missing')` (#135037)

  Addresses CVEs 2024-12718, 2025-4138, 2025-4330, and 2025-4517.

Signed-off-by: Łukasz Langa <lukasz@langa.pl>
Reviewed-by: Jennifer Sutton <jennifersutton@catalyst.net.nz>
Co-authored-by: Petr Viktorin <encukou@gmail.com>
Co-authored-by: Seth Michael Larson <seth@python.org>
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
our ../../ test that looks for a tarfile.OutsideDestinationError now
meets a NotADirectoryError in recent Python versions (this from 3.13,
Fedora 42):

UNEXPECTED(error): samba.tests.safe_tarfile.samba.tests.safe_tarfile.SafeTarFileTestCase.test_dots(none)
REASON: Exception: Exception: Traceback (most recent call last):
  File "/tmp/samba-testbase/b1/samba-o3/bin/python/samba/tests/safe_tarfile.py", line 48, in test_dots
    self.assertRaises(tarfile.OutsideDestinationError,
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                      stf.extractall,
                      ^^^^^^^^^^^^^^^
                      tarname)
                      ^^^^^^^^
  File "/usr/lib64/python3.13/unittest/case.py", line 795, in assertRaises
    return context.handle('assertRaises', args, kwargs)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.13/unittest/case.py", line 238, in handle
    callable_obj(*args, **kwargs)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.13/tarfile.py", line 2343, in extractall
    tarinfo, unfiltered = self._get_extract_tarinfo(
                          ~~~~~~~~~~~~~~~~~~~~~~~~~^
        member, filter_function, path)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.13/tarfile.py", line 2432, in _get_extract_tarinfo
    self._handle_fatal_error(e)
    ~~~~~~~~~~~~~~~~~~~~~~~~^^^
  File "/usr/lib64/python3.13/tarfile.py", line 2430, in _get_extract_tarinfo
    filtered = filter_function(unfiltered, path)
  File "/usr/lib64/python3.13/tarfile.py", line 842, in tar_filter
    new_attrs = _get_filtered_attrs(member, dest_path, False)
  File "/usr/lib64/python3.13/tarfile.py", line 783, in _get_filtered_attrs
    target_path = os.path.realpath(os.path.join(dest_path, name),
                                   strict=os.path.ALLOW_MISSING)
  File "<frozen posixpath>", line 457, in realpath
NotADirectoryError: [Errno 20] Not a directory: '/tmp/samba-testbase/b1/samba-o3/bin/ab/tmp/tmpbn6e69ci/tar.tar'

In this commit, we say that a NotADirectoryError is OK.

When we started safe_tarfile we were acting in advance of upstream
Python, but now they are well ahead of us. If we trust their work in
recent versions and accept the error conditions they choose, we can
more easily get rid of our safe_tarfile when the time is right.

For the moment we still support as far back as Python 3.6 for some old
enterprise distros, and it is for those that we continue to maintain
safe_tarfile. In versions before 3.11 we will see
tarfile.ExtractError, and the test for that is unaffected by this
change.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
python/samba/tests/safe_tarfile.py