Repository navigation
[3.14] gh-157579: Fix race condition in the cleanup of tempfile.TemporaryDirectory (GH-157580) - #158430
Conversation
…raryDirectory` (pythonGH-157580) (cherry picked from commit 5c20517) Co-authored-by: Stan Ulbrych <stan@python.org> Co-authored-by: Petr Viktorin <encukou@gmail.com>
Documentation build overview
310 files changed ·
|
This partially backports commit 86b8617 (pythonGH-146195); making existing tests use the helper is omitted.
|
!buildbot root |
|
🤖 New build scheduled with the buildbot fleet by @encukou for commit fb187f1 🤖 Results will be shown at: https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F158430%2Fmerge The command will test the builders whose names match following regular expression: The builders matched are:
|
|
!buildbot Android |
|
🤖 New build scheduled with the buildbot fleet by @encukou for commit fb187f1 🤖 Results will be shown at: https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F158430%2Fmerge The command will test the builders whose names match following regular expression: The builders matched are:
|
…1527) Grype matches CVE-2026-12345 (TemporaryDirectory cleanup race, medium) against the python 3.14.8 binary in the base image and lists a fix only in 3.15.0. The fix is merged on main and 3.15 (python/cpython#157580, #158431); the 3.14 backport (python/cpython#158430) is still open. Refs #1412 Signed-off-by: Jürgen Kreileder <jk@blackdown.de>
|
🤖 New build scheduled with the buildbot fleet by @encukou for commit fb187f1 🤖 Results will be shown at: https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F158430%2Fmerge If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again. |
|
Buildbot failures are pre-existing or unrelated. |
|
Thanks @miss-islington for the PR, and @encukou for merging it 🌮🎉.. I'm working now to backport this PR to: 3.12. |
|
Sorry, @miss-islington and @encukou, I could not cleanly backport this to Please backport manually with cherry_picker, see the devguide for more information. |
|
GH-159074 is a backport of this pull request to the 3.12 branch. |
…86351) - 3.14.8_git20261008 → 3.14.8_git20261014 (43a8cdc5): includes 58ed0259 (python/cpython#158430), CVE-2026-12345 - epoch 1 → 0 Signed-off-by: Brian Carey <brian.carey@chainguard.dev> Export: 184aecb619f668b88e22293178b1c4d328061be2
…oraryDirectory` (GH-157580) (GH-158430) (#159074) * [3.12] gh-157579: Fix race condition in the cleanup of `tempfile.TemporaryDirectory` (GH-157580) (GH-158430) * gh-157579: Fix race condition in the cleanup of `tempfile.TemporaryDirectory` (GH-157580) (cherry picked from commit 5c20517) * Add root user checks to test.support This partially backports commit 86b8617 (GH-146195); making existing tests use the helper is omitted. --------- (cherry picked from commit 58ed025) Co-authored-by: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Co-authored-by: Stan Ulbrych <stan@python.org> Co-authored-by: Petr Viktorin <encukou@gmail.com> * gh-134993: Add os.lstat() to os.supports_dir_fd (#135188) --------- Co-authored-by: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Co-authored-by: Stan Ulbrych <stan@python.org> Co-authored-by: Victor Stinner <vstinner@python.org>
….TemporaryDirectory (CVE-2026-12345) When TemporaryDirectory cleanup recovers from a PermissionError it resets permissions and retries removal. It did that by resolving paths again, so an attacker who could modify the tree during cleanup could replace a directory with a symlink and make cleanup delete files, or reset their permissions and flags, outside of the temporary directory. Files are now handled relative to the open directory file descriptors that the fd-based shutil.rmtree() walk already holds. Port of the upstream fix (pythonGH-157580, pythonGH-158430), based on the 3.12 backport (python#159074), plus pythongh-134993 (os.lstat in os.supports_dir_fd). 3.10.22.x: the 3.12 fix relies on 3.12's shutil.rmtree() API (onexc, a public dir_fd parameter, and the _onexc_kwargs switch that passes direntry/dir_fd to the callback). 3.10 only has onerror and a recursive _rmtree_safe_fd(), so this adds the private keyword arguments _dir_fd and _onerror_kwargs to rmtree() instead and threads the parent directory fd and os.DirEntry through _rmtree_safe_fd(). With _onerror_kwargs left false, existing onerror callbacks get the same three positional arguments as before. TemporaryDirectory._rmtree() is ported onto the 3.11 shape of the code (bpo-43153 and pythongh-79325 are picked first), using os.lstat(base, dir_fd=...) where 3.12 uses os.path.isdir()/isjunction() on the full path. Tests are adapted: onerror instead of onexc, local root and platform skips instead of support.requires_non_root_user and PY_SUPPORT_TIER. (cherry picked from commit c39b52d) (cherry picked from commit 5c20517) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…TemporaryDirectory (CVE-2026-12345) When TemporaryDirectory cleanup recovers from a PermissionError it resets permissions and retries removal. It did that by resolving paths again, so an attacker who could modify the tree during cleanup could replace a directory with a symlink and make cleanup delete files, or reset their permissions and flags, outside of the temporary directory. Files are now handled relative to the open directory file descriptors that the fd-based shutil.rmtree() walk already holds. Port of the upstream fix (pythonGH-157580, pythonGH-158430), based on the 3.12 backport (python#159074), plus pythongh-134993 (os.lstat in os.supports_dir_fd). 3.10.22.x: the 3.12 fix relies on 3.12's shutil.rmtree() API (onexc, a public dir_fd parameter, and the _onexc_kwargs switch that passes direntry/dir_fd to the callback). 3.10 only has onerror and a recursive _rmtree_safe_fd(), so this adds the private keyword arguments _dir_fd and _onerror_kwargs to rmtree() instead and threads the parent directory fd and os.DirEntry through _rmtree_safe_fd(). With _onerror_kwargs left false, existing onerror callbacks get the same three positional arguments as before. TemporaryDirectory._rmtree() is ported onto the 3.11 shape of the code (bpo-43153 and pythongh-79325 are picked first), using os.lstat(base, dir_fd=...) where 3.12 uses os.path.isdir()/isjunction() on the full path. Tests are adapted: onerror instead of onexc, local root and platform skips instead of support.requires_non_root_user and PY_SUPPORT_TIER. (cherry picked from commit c39b52d) (cherry picked from commit 5c20517) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 776b466) 3.9.25.x: tests use test.support instead of test.support.os_helper, and test_parent_mode_preserved only covers the default (no ignore_errors) case because 3.9's TemporaryDirectory has no ignore_cleanup_errors.
(cherry picked from commit 5c20517)
Co-authored-by: Stan Ulbrych stan@python.org
Co-authored-by: Petr Viktorin encukou@gmail.com
tempfile.TemporaryDirectory#157579