Skip to content

gh-151416: fix a borrowed ref potential use after free via fspath in os.spawnv/spawnve#151417

Merged
gpshead merged 2 commits into
python:mainfrom
gpshead:fsconverter-borrowed-ref-uaf
Jun 29, 2026
Merged

gh-151416: fix a borrowed ref potential use after free via fspath in os.spawnv/spawnve#151417
gpshead merged 2 commits into
python:mainfrom
gpshead:fsconverter-borrowed-ref-uaf

Conversation

@gpshead

@gpshead gpshead commented Jun 12, 2026

Copy link
Copy Markdown
Member

…h__ mutates argv

The argv conversion loops passed references borrowed from the argv list
into fsconvert_strdup().  An item's __fspath__() can mutate the list and
release its reference to the item, leaving the converter operating on a
freed object.  A shrunk list could also make PyList_GetItem() return
NULL, which PyUnicode_FS{Converter,Decoder}() treat as a request to
release an uninitialized output variable.

Hold a strong reference to each item across the conversion, matching
parse_arglist() and parse_envlist().
@gpshead gpshead self-assigned this Jun 12, 2026
@gpshead gpshead requested a review from ZeroIntensity as a code owner June 12, 2026 17:33
@gpshead gpshead changed the title gh151416: fix a borrowed ref potential use after free via fspath in os.spawnv/spawnve gh-151416: fix a borrowed ref potential use after free via fspath in os.spawnv/spawnve Jun 12, 2026
@read-the-docs-community

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #33116238 | 📁 Comparing 3cf0199 against main (f4f1020)

  🔍 Preview build  

3 files changed
± c-api/sys.html
± c-api/unicode.html
± whatsnew/changelog.html

@gpshead gpshead added needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes needs backport to 3.15 pre-release feature fixes, bugs and security fixes labels Jun 12, 2026

@serhiy-storchaka serhiy-storchaka 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.

Tests?

Comment thread Doc/c-api/sys.rst Outdated
Comment thread Modules/posixmodule.c
@gpshead gpshead force-pushed the fsconverter-borrowed-ref-uaf branch from 3cf0199 to 8da22af Compare June 28, 2026 20:59
@gpshead

gpshead commented Jun 28, 2026

Copy link
Copy Markdown
Member Author

Tests?

in this case, i feel like these are each just a specific example of C API misuse. I don't think we need a specific regression test everywhere we've misused the C API once.

I had a test that had been included in #151404 removed for similar reason. That PR was what made me have a claude look over the codebase to find additional occurrances of the API misuse pattern and create this.

…s.spawnv

os.spawnv() replaced any error raised during argv item conversion,
such as MemoryError, codec errors, or the embedded-null ValueError,
with a generic TypeError.  Only add the contextual message when the
conversion actually raised TypeError, matching how os.spawnve() and
the exec functions propagate these errors.

The test is gated to the native C spawnv: the Python fallback used
elsewhere reports conversion failures from the forked child as exit
status 127 instead of raising.
@gpshead gpshead force-pushed the fsconverter-borrowed-ref-uaf branch from 3c3123d to daf288e Compare June 28, 2026 21:12
@gpshead gpshead merged commit f57d3d6 into python:main Jun 29, 2026
54 checks passed
@miss-islington-app

Copy link
Copy Markdown

Thanks @gpshead for the PR 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14, 3.15.
🐍🍒⛏🤖

@miss-islington-app

Copy link
Copy Markdown

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

cherry_picker f57d3d6db39ea0bd39743f1a614b46cbefbfdab6 3.14

@bedevere-app

bedevere-app Bot commented Jun 29, 2026

Copy link
Copy Markdown

GH-152535 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 Jun 29, 2026
@miss-islington-app

Copy link
Copy Markdown

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

cherry_picker f57d3d6db39ea0bd39743f1a614b46cbefbfdab6 3.13

@bedevere-app

bedevere-app Bot commented Jun 29, 2026

Copy link
Copy Markdown

GH-152536 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 Jun 29, 2026
@gpshead gpshead removed the needs backport to 3.13 bugs and security fixes label Jun 29, 2026
gpshead added a commit that referenced this pull request Jun 29, 2026
…ath in os.spawnv/spawnve (GH-151417) (#152535)

gh-151416: fix a borrowed ref potential use after free via fspath in os.spawnv/spawnve (GH-151417)

* gh-151416: Fix use-after-free in os.spawnv/spawnve when __fspath__ mutates argv

The argv conversion loops passed references borrowed from the argv list
into fsconvert_strdup().  An item's __fspath__() can mutate the list and
release its reference to the item, leaving the converter operating on a
freed object.  A shrunk list could also make PyList_GetItem() return
NULL, which PyUnicode_FS{Converter,Decoder}() treat as a request to
release an uninitialized output variable.

Hold a strong reference to each item across the conversion, matching
parse_arglist() and parse_envlist().

* gh-151416: Don't mask non-TypeError argv conversion errors in os.spawnv

os.spawnv() replaced any error raised during argv item conversion,
such as MemoryError, codec errors, or the embedded-null ValueError,
with a generic TypeError.  Only add the contextual message when the
conversion actually raised TypeError, matching how os.spawnve() and
the exec functions propagate these errors.

The test is gated to the native C spawnv: the Python fallback used
elsewhere reports conversion failures from the forked child as exit
status 127 instead of raising.
(cherry picked from commit f57d3d6)

Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
gpshead added a commit that referenced this pull request Jun 29, 2026
…ath in os.spawnv/spawnve (GH-151417) (#152536)

gh-151416: fix a borrowed ref potential use after free via fspath in os.spawnv/spawnve (GH-151417)

* gh-151416: Fix use-after-free in os.spawnv/spawnve when __fspath__ mutates argv

The argv conversion loops passed references borrowed from the argv list
into fsconvert_strdup().  An item's __fspath__() can mutate the list and
release its reference to the item, leaving the converter operating on a
freed object.  A shrunk list could also make PyList_GetItem() return
NULL, which PyUnicode_FS{Converter,Decoder}() treat as a request to
release an uninitialized output variable.

Hold a strong reference to each item across the conversion, matching
parse_arglist() and parse_envlist().

* gh-151416: Don't mask non-TypeError argv conversion errors in os.spawnv

os.spawnv() replaced any error raised during argv item conversion,
such as MemoryError, codec errors, or the embedded-null ValueError,
with a generic TypeError.  Only add the contextual message when the
conversion actually raised TypeError, matching how os.spawnve() and
the exec functions propagate these errors.

The test is gated to the native C spawnv: the Python fallback used
elsewhere reports conversion failures from the forked child as exit
status 127 instead of raising.

(cherry picked from commit f57d3d6)
gpshead added a commit that referenced this pull request Jun 29, 2026
…ath in os.spawnv/spawnve (GH-151417) (GH-152536) (#152539)

[3.14] gh-151416: fix a borrowed ref potential use after free via fspath in os.spawnv/spawnve (GH-151417) (GH-152536)

gh-151416: fix a borrowed ref potential use after free via fspath in os.spawnv/spawnve (GH-151417)

* gh-151416: Fix use-after-free in os.spawnv/spawnve when __fspath__ mutates argv

The argv conversion loops passed references borrowed from the argv list
into fsconvert_strdup().  An item's __fspath__() can mutate the list and
release its reference to the item, leaving the converter operating on a
freed object.  A shrunk list could also make PyList_GetItem() return
NULL, which PyUnicode_FS{Converter,Decoder}() treat as a request to
release an uninitialized output variable.

Hold a strong reference to each item across the conversion, matching
parse_arglist() and parse_envlist().

* gh-151416: Don't mask non-TypeError argv conversion errors in os.spawnv

os.spawnv() replaced any error raised during argv item conversion,
such as MemoryError, codec errors, or the embedded-null ValueError,
with a generic TypeError.  Only add the contextual message when the
conversion actually raised TypeError, matching how os.spawnve() and
the exec functions propagate these errors.

The test is gated to the native C spawnv: the Python fallback used
elsewhere reports conversion failures from the forked child as exit
status 127 instead of raising.
(cherry picked from commit 11a2482)


(cherry picked from commit f57d3d6)

Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.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.

Use-after-free in os.spawnv/spawnve when __fspath__ mutates argv

2 participants