Skip to content

gh-149486: tarfile.data_filter: validate written link target - #149487

Merged
encukou merged 3 commits into
python:mainfrom
encukou:tarfile-validate-written-link-target
May 8, 2026
Merged

gh-149486: tarfile.data_filter: validate written link target#149487
encukou merged 3 commits into
python:mainfrom
encukou:tarfile-validate-written-link-target

Conversation

@encukou

@encukou encukou commented May 7, 2026

Copy link
Copy Markdown
Member
gpshead and others added 3 commits May 4, 2026 19:14
The data filter rewrote linknames with normpath() but ran the
containment check against the un-normalised value, and computed a
symlink's directory before stripping trailing slashes.  Both let a
crafted archive create links pointing outside the destination.  Also
reject link members that resolve to the destination directory itself,
which could otherwise replace it with a symlink and redirect all
subsequent members.
@StanFromIreland StanFromIreland added the needs backport to 3.15 pre-release feature fixes, bugs and security fixes label May 7, 2026
@encukou
encukou merged commit 5784119 into python:main May 8, 2026
69 checks passed
@miss-islington-app

Copy link
Copy Markdown

Thanks @encukou for the PR 🌮🎉.. I'm working now to backport this PR to: 3.12, 3.13, 3.14, 3.15.
🐍🍒⛏🤖 I'm not a witch! I'm not a witch!

@encukou
encukou deleted the tarfile-validate-written-link-target branch May 8, 2026 12:16
@bedevere-app

bedevere-app Bot commented May 8, 2026

Copy link
Copy Markdown

GH-149553 is a backport of this pull request to the 3.15 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 pre-release feature fixes, bugs and security fixes label May 8, 2026
@bedevere-app

bedevere-app Bot commented May 8, 2026

Copy link
Copy Markdown

GH-149554 is a backport of this pull request to the 3.14 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.14 bugs and security fixes label May 8, 2026
@bedevere-app

bedevere-app Bot commented May 8, 2026

Copy link
Copy Markdown

GH-149555 is a backport of this pull request to the 3.13 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.13 bugs and security fixes label May 8, 2026
@bedevere-app

bedevere-app Bot commented May 8, 2026

Copy link
Copy Markdown

GH-149556 is a backport of this pull request to the 3.12 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.12 only security fixes label May 8, 2026
encukou pushed a commit that referenced this pull request May 11, 2026
…H-149487) (GH-149553)

gh-149486: tarfile.data_filter: validate written link target (GH-149487)

The data filter rewrote linknames with normpath() but ran the
containment check against the un-normalised value, and computed a
symlink's directory before stripping trailing slashes.  Both let a
crafted archive create links pointing outside the destination.  Also
reject link members that resolve to the destination directory itself,
which could otherwise replace it with a symlink and redirect all
subsequent members.

(cherry picked from commit 5784119)

Co-authored-by: Gregory P. Smith <greg@krypto.org>
encukou added a commit that referenced this pull request May 11, 2026
…H-149487) (GH-149554)

* gh-149486: tarfile.data_filter: validate written link target (GH-149487)

The data filter rewrote linknames with normpath() but ran the
containment check against the un-normalised value, and computed a
symlink's directory before stripping trailing slashes.  Both let a
crafted archive create links pointing outside the destination.  Also
reject link members that resolve to the destination directory itself,
which could otherwise replace it with a symlink and redirect all
subsequent members.

(Patch by Greg; Petr's just reviewing & merging.)
(cherry picked from commit 5784119)

Co-authored-by: Petr Viktorin <encukou@gmail.com>
Co-authored-by: Gregory P. Smith <greg@krypto.org>
encukou added a commit that referenced this pull request May 11, 2026
…H-149487) (GH-149555)

* gh-149486: tarfile.data_filter: validate written link target (GH-149487)

The data filter rewrote linknames with normpath() but ran the
containment check against the un-normalised value, and computed a
symlink's directory before stripping trailing slashes.  Both let a
crafted archive create links pointing outside the destination.  Also
reject link members that resolve to the destination directory itself,
which could otherwise replace it with a symlink and redirect all
subsequent members.

(Patch by Greg; Petr's just reviewing & merging.)
(cherry picked from commit 5784119)

Co-authored-by: Petr Viktorin <encukou@gmail.com>
Co-authored-by: Gregory P. Smith <greg@krypto.org>
@bedevere-bot

Copy link
Copy Markdown

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot AMD64 Fedora Stable LTO 3.15 (tier-1) has failed when building commit 5cf47a2.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/2090/builds/16) and take a look at the build logs.
  4. Check if the failure is related to this commit (5cf47a2) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/#/builders/2090/builds/16

Failed tests:

  • test.test_multiprocessing_fork.test_processes

Failed subtests:

  • test_interrupt - test.test_multiprocessing_fork.test_processes.WithProcessesTestProcess.test_interrupt

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/contextlib.py", line 116, in inner
    return func(*args, **kwds)
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/test/_test_multiprocessing.py", line 649, in test_interrupt
    exitcode = self._kill_process(multiprocessing.Process.interrupt)
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/contextlib.py", line 116, in inner
    return func(*args, **kwds)
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/test/_test_multiprocessing.py", line 630, in _kill_process
    self.assertEqual(join(), None)
                     ~~~~^^
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/test/_test_multiprocessing.py", line 303, in __call__
    return self.func(*args, **kwds)
           ~~~~~~~~~^^^^^^^^^^^^^^^
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/multiprocessing/process.py", line 156, in join
    res = self._popen.wait(timeout)
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/multiprocessing/popen_fork.py", line 44, in wait
    return self.poll(os.WNOHANG if timeout == 0.0 else 0)
           ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/multiprocessing/popen_fork.py", line 28, in poll
    pid, sts = os.waitpid(self.pid, flag)
               ~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/test/_test_multiprocessing.py", line 626, in handler
    raise RuntimeError('join took too long: %s' % p)
RuntimeError: join took too long: <Process name='Process-157' pid=3262808 parent=3260155 started daemon>


Traceback (most recent call last):
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/contextlib.py", line 116, in inner
    return func(*args, **kwds)
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/test/_test_multiprocessing.py", line 649, in test_interrupt
    exitcode = self._kill_process(multiprocessing.Process.interrupt)
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/contextlib.py", line 116, in inner
    return func(*args, **kwds)
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/test/_test_multiprocessing.py", line 630, in _kill_process
    self.assertEqual(join(), None)
                     ~~~~^^
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/test/_test_multiprocessing.py", line 303, in __call__
    return self.func(*args, **kwds)
           ~~~~~~~~~^^^^^^^^^^^^^^^
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/multiprocessing/process.py", line 156, in join
    res = self._popen.wait(timeout)
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/multiprocessing/popen_fork.py", line 44, in wait
    return self.poll(os.WNOHANG if timeout == 0.0 else 0)
           ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/multiprocessing/popen_fork.py", line 28, in poll
    pid, sts = os.waitpid(self.pid, flag)
               ~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "/home/buildbot-worker/cstratak-fedora-stable-x86_64/3.15.cstratak-fedora-stable-x86_64.lto/build/Lib/test/_test_multiprocessing.py", line 626, in handler
    raise RuntimeError('join took too long: %s' % p)
RuntimeError: join took too long: <Process name='Process-1' pid=3282745 parent=3282743 started daemon>
Yhg1s pushed a commit that referenced this pull request May 18, 2026
…H-149487) (#149556)

* gh-149486: tarfile.data_filter: validate written link target (GH-149487)

The data filter rewrote linknames with normpath() but ran the
containment check against the un-normalised value, and computed a
symlink's directory before stripping trailing slashes.  Both let a
crafted archive create links pointing outside the destination.  Also
reject link members that resolve to the destination directory itself,
which could otherwise replace it with a symlink and redirect all
subsequent members.

(Patch by Greg; Petr's just reviewing & merging.)
(cherry picked from commit 5784119)

Co-authored-by: Petr Viktorin <encukou@gmail.com>
Co-authored-by: Gregory P. Smith <greg@krypto.org>

* Move dotdot_resolves_early setting to setUpClass

---------

Co-authored-by: Petr Viktorin <encukou@gmail.com>
Co-authored-by: Gregory P. Smith <greg@krypto.org>
@StanFromIreland

Copy link
Copy Markdown
Member

Does this not need backporting to 3.11 and 3.10?

@encukou encukou added needs backport to 3.10 only security fixes needs backport to 3.11 only security fixes labels Jun 4, 2026
@miss-islington-app

Copy link
Copy Markdown

Thanks @encukou for the PR 🌮🎉.. I'm working now to backport this PR to: 3.11.
🐍🍒⛏🤖

@miss-islington-app

Copy link
Copy Markdown

Thanks @encukou for the PR 🌮🎉.. I'm working now to backport this PR to: 3.10.
🐍🍒⛏🤖

@miss-islington-app

Copy link
Copy Markdown

Sorry, @encukou, I could not cleanly backport this to 3.10 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 578411982c16f753f4893532510099ef665117da 3.10
@bedevere-app

bedevere-app Bot commented Jun 4, 2026

Copy link
Copy Markdown

GH-150904 is a backport of this pull request to the 3.11 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.11 only security fixes label Jun 4, 2026
pablogsal pushed a commit that referenced this pull request Jul 4, 2026
…H-149487) (#150904)

* gh-149486: tarfile.data_filter: validate written link target (GH-149487)

The data filter rewrote linknames with normpath() but ran the
containment check against the un-normalised value, and computed a
symlink's directory before stripping trailing slashes.  Both let a
crafted archive create links pointing outside the destination.  Also
reject link members that resolve to the destination directory itself,
which could otherwise replace it with a symlink and redirect all
subsequent members.

(Patch by Greg; Petr's just reviewing & merging.)
(cherry picked from commit 5784119)

Co-authored-by: Petr Viktorin <encukou@gmail.com>
Co-authored-by: Gregory P. Smith <greg@krypto.org>

* Move dotdot_resolves_early setting to setUpClass

---------

Co-authored-by: Petr Viktorin <encukou@gmail.com>
Co-authored-by: Gregory P. Smith <greg@krypto.org>
@bedevere-app

bedevere-app Bot commented Jul 6, 2026

Copy link
Copy Markdown

GH-153180 is a backport of this pull request to the 3.10 branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

4 participants