8000 python: backport gh-157579 (CVE-2026-12345, tempfile cleanup race) to 3.14.8 by bryan-minimal · Pull Request #895 · gominimal/pkgs · GitHub
[go: up one dir, main page]

Skip to content

python: backport gh-157579 (CVE-2026-12345, tempfile cleanup race) to 3.14.8 - #895

Merged
bryan-minimal merged 1 commit into
mainfrom
python-backport-gh157579
Oct 21, 2026
Merged

bryan-minimal merged 1 commit into
mainfrom
python-backport-gh157579

Conversation

@bryan-minimal
@bryan-minimal bryan-minimal commented Oct 16, 2026 •
Copy link
Copy Markdown
Member

Why

We're staying on Python 3.14 for now. #891 (→ 3.15.0) is closed because the released node-lts configure rejects Python 3.15 and the bump rebuilds 100+ packages. Of the 3 advisories 3.15.0 cleared, 3.14.8 already carries patches for two (poplib gh-143923, tarfile gh-157265). This PR covers the third:

CVE-2026-12345 / PSF-2026-42 (MEDIUM), gh-157579. tempfile.TemporaryDirectory cleanup re-resolved paths while resetting permissions. An attacker who can modify the tree during cleanup can replace a directory with a symlink and cause files outside the temporary directory to be removed.

What

  • 0004-gh-157579-tempfile-cleanup-race.patch is upstream's own 3.14 backport: [3.14] gh-157579: Fix race condition in the cleanup of tempfile.TemporaryDirectory (GH-157580) python/cpython#158430, merge 58ed0259, merged to 3.14 on 2026-10-09, after 3.14.8 was cut. It is carried byte-for-byte.
    • It applies to v3.14.8 at fuzz 0 (patch -p1 -N -F0 --dry-run).
    • It touches none of the files 0002/0003 change.
  • build.sh applies it the same fail-closed way as 0002/0003.
  • The build.ncl comment records where it came from, plus the drop condition: the first 3.14.x whose changelog lists gh-157579, which should be 3.14.9. From now on pkgmgr's updater checks this itself and removes patches that are already upstream (pkgmgr-rs#988).

Test

tempfile_cleanup_race_fix (Standalone). The race itself can't be reproduced deterministically, so the test guards the fix's presence and normal behaviour:

  • tempfile._rmtree_use_dir_fd is True, meaning cleanup works relative to open directory fds;
  • shutil.rmtree has the _onexc_kwargs parameter;
  • a TemporaryDirectory containing a read-only subdirectory, which forces the permission-reset path the fix rewrote, still cleans up completely.

I checked the test script locally with Python 3.14 against the stock and patched tempfile.py/shutil.py: stock fails (both presence checks), patched passes. This was not a package build; CI/buildbot will build it.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Temporary directories now clean up more reliably when files or subdirectories have restricted permissions, including in situations that could previously cause cleanup failures or race conditions.
    • Cleanup errors continue to be reported unless error suppression is explicitly enabled.
    • Python 3.14.8 includes the updated cleanup behavior.

… 3.14.8

TemporaryDirectory cleanup re-resolved paths while resetting permissions,
so an attacker able to modify the tree during cleanup could swap a
directory for a symlink and have files outside the temporary directory
removed (PSF-2026-42). Carry upstream's own 3.14 backport
(python/cpython#158430, merge 58ed0259, merged 2026-10-09, after 3.14.8)
byte-for-byte; it applies at fuzz 0 to 3.14.8 and touches none of the
files 0002/0003 change.

Regression test tempfile_cleanup_race_fix: fails on stock 3.14.8 (no
dir-fd cleanup, no rmtree onexc kwargs), passes with the patch, and
checks a read-only subtree still cleans up completely.

We stay on the 3.14 series (pkgs#891 closed: node-lts's configure
rejects Python 3.15); this was the one advisory 3.15.0 fixed that 3.14.8
lacked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bryan-minimal
bryan-minimal requested a review from a team as a code owner October 16, 2026 16:07
@coderabbitai
coderabbitai Bot commented Oct 16, 2026 •
Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: gominimal/pkgs/.coderabbit.yaml
  • Review 8000 profile: CHILL
  • Plan: Essentials
  • Run ID: 7fb690b7-24de-4229-aad6-d04e1c7a94ee
📥 Commits

Reviewing files that changed from the base of the PR and between b3016f1 and eacb33d.

📒 Files selected for processing: 3
  • packages/python/0004-gh-157579-tempfile-cleanup-race.patch
  • packages/python/build.ncl
  • packages/python/build.sh

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

📝 Walkthrough

The Python build applies a patch that adds directory-relative cleanup and callback context to TemporaryDirectory cleanup. The patch adds permission-recovery helpers, regression tests, and documentation about cleanup races and symlink-related risks.

Changes: TemporaryDirectory cleanup race handling

Layer / File(s) Summary
Pass directory context to rmtree callbacks
packages/python/0004-gh-157579-tempfile-cleanup-race.patch
shutil.rmtree can pass the failing entry and parent directory fd to opted-in onexc callbacks. A test checks the callback context.
Recover permissions and clean up relative to open directories
packages/python/0004-gh-157579-tempfile-cleanup-race.patch
TemporaryDirectory resets permissions and flags with directory-relative operations where supported, and uses guarded fallbacks otherwise. Tests cover symlink replacement, parent permissions, and platform support. The patch documents cleanup race risks.
Apply and check the patch
packages/python/build.ncl, packages/python/build.sh
The Python build includes and applies the patch before configuration. A build test checks for cleanup indicators and removes a tree with a read-only subdirectory.

Priority: ⬆️ High

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to eacb3

No confirmed issue blocks merging. The Python build and tests still need normal CI validation.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies the main change: backporting the gh-157579 tempfile cleanup race fix to Python 3.14.8.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1 files. (2 skipped: 2 unsupported.)

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@bryan-minimal
Copy link
Copy Markdown
Member Author

/build

@norrietaylor norrietaylor left a comment
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. The patch is identical to the upstream 3.14 backport 58ed0259 (GH-158430); only the hunk-header context differs. It's not in v3.14.8, applies cleanly, and is wired in before configure.

Nit, build.ncl:353: os.chmod(sub, S_IRUSR|S_IXUSR) won't force the permission-reset path if tests run as root. The presence checks still keep the test meaningful.


Generated by Claude Code

@bryan-minimal
bryan-minimal added this pull request to the merge queue Oct 19, 2026
@bryan-minimal
bryan-minimal removed this pull request from the merge queue due to a manual request Oct 19, 2026
@bryan-minimal
bryan-minimal added this pull request to the merge queue Oct 19, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Oct 19, 2026
@bryan-minimal
bryan-minimal added this pull request to the merge queue Oct 20, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 20, 2026
bryan-minimal added a commit that referenced this pull request Oct 20, 2026
classpath-0.93 failed on pkgs#895 (a python-only change) with
`sort: /usr/lib/libc.so.6: version GLIBC_2.43 not found`. The rungs
depend on the whole glibc-bedrock-2.42, and its sealed amd64 tarball
carries a full glibc 2.42 at /usr/lib (listed: usr/lib/libc.so.6,
ld-linux-x86-64.so.2, 4087 entries), whatever its output globs say. That
collides with production glibc 2.44 path for path (~1400 files); the
sandbox keeps whichever lands first ("Not linking ... already exists"),
which shifts with fetch timing, so an unrelated python change flipped
classpath's /usr/lib/libc.so.6 to 2.42 and every production tool in the
sandbox stopped loading.

The new glibc-bedrock-2.42-sysroot collection carries only
usr/lib/glibc-bedrock-2.42/{lib,include}, all the rungs use (SR=), and
the 28 rungs import it in place of glibc-bedrock-2.42. A collection
because `subsetOf` is only supported in runtime_deps: in build_deps it
panics minimal's executor (op/src/specs.rs:88, todo!), which is what
stopped #937.

Verified on the lab (amd64, mip): main + #895's python + this builds
jikes-1.22 and classpath-0.93 (rc=0), with no glibc path conflict in
classpath's sandbox; without it, the same tree reproduces the failure.
Rebuilds the amd64 JVM ladder once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bryan-minimal
bryan-minimal added this pull request to the merge queue Oct 20, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Oct 20, 2026
@bryan-minimal
bryan-minimal added this pull request to the merge queue Oct 20, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Oct 20, 2026
@bryan-minimal
bryan-minimal added this pull request to the merge queue Oct 21, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Oct 21, 2026
@bryan-minimal
bryan-minimal added this pull request to the merge queue Oct 21, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Oct 21, 2026
@bryan-minimal
bryan-minimal added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit a19e4dc Oct 21, 2026
11 checks passed
@bryan-minimal
bryan-minimal deleted the python-backport-gh157579 branch October 21, 2026 20:26
bryan-minimal added a commit that referenced this pull request Oct 21, 2026
….2.2 swap

main gained #941 (JVM ladder takes only the bedrock sysroot; the classpath
glibc collision that failed #950's amd64 leg) and #895 (gh-157579 patch),
which conflicted here only by adding beside this PR's pip wheel. Both kept:
the 0004 patch with the other patches, then the ensurepip wheel swap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0