GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-152682: Fix NULL dereference on OOM in symtable_visit_type_param_bound_or_default by petrvaganoff · Pull Request #152684 · python/cpython

Conversation

@petrvaganoff

@petrvaganoff petrvaganoff commented Jun 30, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

When a reserved name (e.g. __classdict__) is used as a type parameter,
symtable_visit_type_param_bound_or_default() calls PyUnicode_FromFormat()
to build the SyntaxError message. If the allocation fails and returns NULL,
the subsequent PyErr_SetObject(PyExc_SyntaxError, NULL) and Py_DECREF(NULL)
calls dereference the null pointer, causing a segfault.

Fix by returning 0 immediately when PyUnicode_FromFormat() returns NULL,
which propagates the MemoryError already set by PyUnicode_FromFormat().

The bug was introduced in gh-128632 (commit 891c61c).

Found by static analyzer Svace (ISP RAS).

  • Add a NEWS entry in Misc/NEWS.d/
  • Add regression test (test_disallowed_type_param_names_oom)
  • Issue: symtable: NULL dereference after OOM in PyUnicode_FromFormat (symtable_visit_type_param_bound_or_default) #152682

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@petrvaganoff
petrvaganoff requested review from JelleZijlstra and carljm as code owners June 30, 2026 13:57
@python-cla-bot

python-cla-bot Bot commented Jun 30, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot mentioned this pull request Jun 30, 2026
symtable: NULL dereference after OOM in PyUnicode_FromFormat (symtable_visit_type_param_bound_or_default) #152682
Closed
@bedevere-app bedevere-app Bot added the awaiting review label Jun 30, 2026
sobolevn
sobolevn reviewed Jun 30, 2026
View reviewed changes

@sobolevn sobolevn left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Don't forget to add else: raise RuntimeError('Not raised') as well :)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/test/test_syntax.py Outdated
code = textwrap.dedent("""\
import _testcapi
_testcapi.set_nomemory(0)
compile("class A[__classdict__]: pass", "<string>", "exec")

@sobolevn sobolevn Jun 30, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Can we catch the MemoryError here? And just assert that script works correctly with assert_python_ok?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@petrvaganoff petrvaganoff Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Thanks, done, updated the test to catch MemoryError and use assert_python_ok. Imports fixed.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@petrvaganoff
petrvaganoff force-pushed the dev branch from 36fa94e to c284d9c Compare June 30, 2026 14:10
sobolevn
sobolevn approved these changes Jun 30, 2026
View reviewed changes
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting review labels Jun 30, 2026
@petrvaganoff
pythongh-152682: Fix NULL dereference on OOM in symtable_visit_type_p…
ad57b62
…aram_bound_or_default

In symtable_visit_type_param_bound_or_default(), when a reserved name
(e.g. __classdict__) is used as a type parameter, PyUnicode_FromFormat()
is called to build the SyntaxError message. If the allocation fails and
returns NULL, the subsequent PyErr_SetObject() and Py_DECREF() calls
would dereference NULL, causing a segfault.

Fix by returning 0 immediately when PyUnicode_FromFormat() returns NULL.
This propagates the MemoryError set by PyUnicode_FromFormat().

The bug was introduced in pythongh-128632 (commit 891c61c).
@petrvaganoff
petrvaganoff force-pushed the dev branch from c284d9c to ad57b62 Compare June 30, 2026 14:13
@sobolevn sobolevn added needs backport to 3.13 only security fixes needs backport to 3.14 bugs and security fixes needs backport to 3.15 bugs and security fixes labels Jun 30, 2026
@sobolevn
sobolevn enabled auto-merge (squash) June 30, 2026 14:15
@sobolevn
sobolevn merged commit 10ed03e into python:main Jun 30, 2026
60 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@miss-islington-app

miss-islington-app Bot commented Jun 30, 2026

Copy link
Copy Markdown

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the awaiting merge label Jun 30, 2026
@bedevere-app

bedevere-app Bot commented Jun 30, 2026

Copy link
Copy Markdown

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 bugs and security fixes label Jun 30, 2026
@bedevere-app

bedevere-app Bot commented Jun 30, 2026

Copy link
Copy Markdown

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

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

bedevere-app Bot commented Jun 30, 2026

Copy link
Copy Markdown

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the needs backport to 3.13 only security fixes label Jun 30, 2026
@sobolevn

sobolevn commented Jun 30, 2026

Copy link
Copy Markdown
Member

Congrats on your first CPython contribution! 🎉

petrvaganoff reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

StanFromIreland
StanFromIreland reviewed Jun 30, 2026
View reviewed changes
Comment thread Lib/test/test_syntax.py
""", "<testcase>", mode="exec")

@support.nomemtest
def test_disallowed_type_param_names_oom(self):

@StanFromIreland StanFromIreland Jun 30, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

This test passes for me on main.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

petrvaganoff reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@petrvaganoff petrvaganoff Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Yes, I also couldn't reproduce it reliably. After investigating, it seems _testcapi.set_nomemory(0) replaces the global CPython allocator with a stub, and there are many allocations happening between the set_nomemory(0) call and PyUnicode_FromFormat inside compile(), so OOM typically hits one of them first. I verified this with a coverage build - the relevant lines are never reached.

I also tried manually injecting an OOM condition in the C code - without the fix it does produce SIGSEGV, confirming the bug is real.

In principle, we could add a fault injection hook in the debug build and expose it via _testinternalcapi. But I think the simpler option is to drop the OOM test entirely - the fix is a straightforward NULL check, and the existing test_disallowed_type_param_names() already covers the code path. What do you think?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@StanFromIreland StanFromIreland Jul 1, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

The test isn't doing anything, please remove it. In general we just don't test these cases.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

petrvaganoff reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@petrvaganoff petrvaganoff Jul 1, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

See please, - #152770

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
This was referenced Jun 30, 2026
[3.15] gh-152682: Fix NULL dereference on OOM in symtable_visit_type_param_bound_or_default (GH-152684) #152695
Merged
[3.14] gh-152682: Fix NULL dereference on OOM in symtable_visit_type_param_bound_or_default (GH-152684) #152696
Merged
[3.13] gh-152682: Fix NULL dereference on OOM in symtable_visit_type_param_bound_or_default (GH-152684) #152697
Merged
@petrvaganoff petrvaganoff mentioned this pull request Jul 1, 2026
gh-152682: Remove useless test_syntax.test_disallowed_type_param_names_oom #152770
Merged
maurycy added a commit to maurycy/cpython that referenced this pull request Jul 1, 2026
@maurycy
Merge branch 'main' into maurycy/bye-abba
da7d768
* main: (266 commits)
  pythongh-151626: Fix tests that fail when PYTHONPYCACHEPREFIX is set (pythonGH-151952)
  pythongh-152728: IDLE - move 3 toplevel fix_xyz functions to idlelb.util (python#152729)
  pythongh-152711: Add pythoninfo-build command to Platforms/Android (python#152713)
  pythongh-152715: Add pythoninfo-build command to Platforms/Apple (python#152716)
  pythongh-152433: Windows: enable mmapmodule for UWP (python#152473)
  pythongh-152433: Windows: use GetFileSizeEx instead of GetFileSize for memory mapped files (python#152383)
  pythonGH-81881: Raise `SpecialFileError` for sockets and devices in `shutil.copyfile` (python#142693)
  pythongh-152502: Detect the curses mouse interface and is_* methods portably (pythonGH-152705)
  pythongh-145857: Replace `DELETE_GLOBAL` with `PUSH_NULL; STORE_GLOBAL` (pythonGH-146314)
  pythongh-145854: Replace `DELETE_NAME` with `PUSH_NULL; STORE_NAME` (pythonGH-146006)
  pythongh-152680: Detect container/VM in test.pythoninfo (python#152668)
  pythongh-152682: Fix NULL dereference on OOM in `symtable_visit_type_param_bound_or_default` (python#152684)
  pythongh-151881: Skip tk_inactive negativity check on Windows (pythonGH-152683)
  pythongh-152546: Refactor `mappingproxy.__new__` to use `PyDictProxy_New` (python#152547)
  pythongh-151126: Fix a possible crash during the startup with no memory under `Py_STACKREF_DEBUG` (python#152478)
  pythongh-152635: Raise MemoryError when the lock allocation fails in `_interpchannels.create()` (python#152642)
  pythongh-151029: Fix `test_remote_exec_deleted_static_executable` on static installed builds (pythonGH-152653)
  pythongh-121249: Deprecate using F/D type codes in the struct module (python#152309)
  pythongh-152192: Fix JUMP_BACKWARD passing a truncated oparg to the jit tracer (pythonGH-152382)
  Don't require the `_test{internal}capi` modules in `test_monitoring.py` (python#152311)
  ...
JelleZijlstra pushed a commit that referenced this pull request Jul 6, 2026
@miss-islington @petrvaganoff @StanFromIreland
[3.14] gh-152682: Fix NULL dereference on OOM in `symtable_visit_type…
0903be8
…_param_bound_or_default` (GH-152684) (#152696)

In `symtable_visit_type_param_bound_or_default()`, when a reserved name
(e.g. `__classdict__`) is used as a type parameter, `PyUnicode_FromFormat()`
is called to build the SyntaxError message. If the allocation fails and
returns NULL, the subsequent `PyErr_SetObject()` and `Py_DECREF()` calls
would dereference NULL, causing a segfault.

Fix by returning 0 immediately when `PyUnicode_FromFormat()` returns NULL.
This propagates the MemoryError set by `PyUnicode_FromFormat()`.

The bug was introduced in gh-128632 (commit 891c61c).
(cherry picked from commit 10ed03e)

Co-authored-by: Petr Vaganov <[email protected]>

* Remove test

---------

Co-authored-by: Petr Vaganov <[email protected]>
Co-authored-by: Stan Ulbrych <[email protected]>
JelleZijlstra pushed a commit that referenced this pull request Jul 6, 2026
@miss-islington @petrvaganoff @StanFromIreland
[3.13] gh-152682: Fix NULL dereference on OOM in `symtable_visit_type…
eca0efe
…_param_bound_or_default` (GH-152684) (#152697)

In `symtable_visit_type_param_bound_or_default()`, when a reserved name
(e.g. `__classdict__`) is used as a type parameter, `PyUnicode_FromFormat()`
is called to build the SyntaxError message. If the allocation fails and
returns NULL, the subsequent `PyErr_SetObject()` and `Py_DECREF()` calls
would dereference NULL, causing a segfault.

Fix by returning 0 immediately when `PyUnicode_FromFormat()` returns NULL.
This propagates the MemoryError set by `PyUnicode_FromFormat()`.

The bug was introduced in gh-128632 (commit 891c61c).
(cherry picked from commit 10ed03e)

Co-authored-by: Petr Vaganov <[email protected]>

* Remove test

---------

Co-authored-by: Petr Vaganov <[email protected]>
Co-authored-by: Stan Ulbrych <[email protected]>
JelleZijlstra pushed a commit that referenced this pull request Jul 6, 2026
@miss-islington @petrvaganoff @StanFromIreland
[3.15] gh-152682: Fix NULL dereference on OOM in `symtable_visit_type…
ffb5184
…_param_bound_or_default` (GH-152684) (#152695)

In `symtable_visit_type_param_bound_or_default()`, when a reserved name
(e.g. `__classdict__`) is used as a type parameter, `PyUnicode_FromFormat()`
is called to build the SyntaxError message. If the allocation fails and
returns NULL, the subsequent `PyErr_SetObject()` and `Py_DECREF()` calls
would dereference NULL, causing a segfault.

Fix by returning 0 immediately when `PyUnicode_FromFormat()` returns NULL.
This propagates the MemoryError set by `PyUnicode_FromFormat()`.

The bug was introduced in gh-128632 (commit 891c61c).
(cherry picked from commit 10ed03e)

Co-authored-by: Petr Vaganov <[email protected]>

* Remove test

---------

Co-authored-by: Petr Vaganov <[email protected]>
Co-authored-by: Stan Ulbrych <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@StanFromIreland StanFromIreland StanFromIreland left review comments
@sobolevn sobolevn sobolevn approved these changes
@JelleZijlstra JelleZijlstra Awaiting requested review from JelleZijlstra JelleZijlstra is a code owner
@carljm carljm Awaiting requested review from carljm carljm is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@petrvaganoff @sobolevn @StanFromIreland
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.