From 26a1c6c0f6d3b70c685a5031b1b28d8e30d1f657 Mon Sep 17 00:00:00 2001 From: "zainnadeem(RedOpsCell)" Date: Mon, 22 Jun 2026 09:53:40 +0500 Subject: [PATCH 1/2] gh-151763: Fix OOM-0014 crash in _interpchannels._channel_id --- Lib/test/test__interpchannels.py | 29 +++++++++++++++++++ ...06-22-09-41-31.gh-issue-151763.OOM0014.rst | 3 ++ Modules/_interpchannelsmodule.c | 3 ++ 3 files changed, 35 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-06-22-09-41-31.gh-issue-151763.OOM0014.rst diff --git a/Lib/test/test__interpchannels.py b/Lib/test/test__interpchannels.py index 2b0aba42896c06a..83775fc979a3556 100644 --- a/Lib/test/test__interpchannels.py +++ b/Lib/test/test__interpchannels.py @@ -6,7 +6,9 @@ import time import unittest +from test import support from test.support import import_helper +from test.support.script_helper import run_python_until_end _channels = import_helper.import_module('_interpchannels') from concurrent.interpreters import _crossinterp @@ -308,6 +310,33 @@ def test_bad_kwargs(self): with self.assertRaises(ValueError): _channels._channel_id(10, send=False, recv=False) + @unittest.skipIf(support.Py_TRACE_REFS, + '_testcapi.set_nomemory() is unreliable with Py_TRACE_REFS') + def test_oom_in_module_lookup(self): + import_helper.import_module('_testcapi') + code = dedent(""" + import _interpchannels + import _testcapi + from test.support import SuppressCrashReport + + seen = False + with SuppressCrashReport(): + _testcapi.set_nomemory(0, 1) + try: + _interpchannels._channel_id(0) + except MemoryError: + seen = True + finally: + _testcapi.remove_mem_hooks() + if not seen: + raise AssertionError("MemoryError not raised") + print("MemoryError") + """) + with support.SuppressCrashReport(): + res, _ = run_python_until_end("-c", code) + self.assertEqual(res.rc, 0, res.err.decode("ascii", "replace")) + self.assertIn(b"MemoryError", res.out) + def test_does_not_exist(self): cid = _channels.create(REPLACE) with self.assertRaises(_channels.ChannelNotFoundError): diff --git a/Misc/NEWS.d/next/Library/2026-06-22-09-41-31.gh-issue-151763.OOM0014.rst b/Misc/NEWS.d/next/Library/2026-06-22-09-41-31.gh-issue-151763.OOM0014.rst new file mode 100644 index 000000000000000..723aafb9f9202e1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-22-09-41-31.gh-issue-151763.OOM0014.rst @@ -0,0 +1,3 @@ +Fix a crash in ``_interpchannels._channel_id()`` when memory allocation +fails while looking up module state. The function now correctly propagates +``MemoryError``. diff --git a/Modules/_interpchannelsmodule.c b/Modules/_interpchannelsmodule.c index 3614890757d69da..1d03c9d3197c4d7 100644 --- a/Modules/_interpchannelsmodule.c +++ b/Modules/_interpchannelsmodule.c @@ -3484,6 +3484,9 @@ channelsmod__channel_id(PyObject *self, PyObject *args, PyObject *kwds) PyTypeObject *cls = state->ChannelIDType; PyObject *mod = get_module_from_owned_type(cls); + if (mod == NULL) { + return NULL; + } assert(mod == self); Py_DECREF(mod); From 97f1148a52d5b0da12da5599a790ec4fd66fea8b Mon Sep 17 00:00:00 2001 From: "zainnadeem(RedOpsCell)" Date: Mon, 22 Jun 2026 19:16:57 +0500 Subject: [PATCH 2/2] Remove OOM regression test --- Lib/test/test__interpchannels.py | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/Lib/test/test__interpchannels.py b/Lib/test/test__interpchannels.py index 83775fc979a3556..2b0aba42896c06a 100644 --- a/Lib/test/test__interpchannels.py +++ b/Lib/test/test__interpchannels.py @@ -6,9 +6,7 @@ import time import unittest -from test import support from test.support import import_helper -from test.support.script_helper import run_python_until_end _channels = import_helper.import_module('_interpchannels') from concurrent.interpreters import _crossinterp @@ -310,33 +308,6 @@ def test_bad_kwargs(self): with self.assertRaises(ValueError): _channels._channel_id(10, send=False, recv=False) - @unittest.skipIf(support.Py_TRACE_REFS, - '_testcapi.set_nomemory() is unreliable with Py_TRACE_REFS') - def test_oom_in_module_lookup(self): - import_helper.import_module('_testcapi') - code = dedent(""" - import _interpchannels - import _testcapi - from test.support import SuppressCrashReport - - seen = False - with SuppressCrashReport(): - _testcapi.set_nomemory(0, 1) - try: - _interpchannels._channel_id(0) - except MemoryError: - seen = True - finally: - _testcapi.remove_mem_hooks() - if not seen: - raise AssertionError("MemoryError not raised") - print("MemoryError") - """) - with support.SuppressCrashReport(): - res, _ = run_python_until_end("-c", code) - self.assertEqual(res.rc, 0, res.err.decode("ascii", "replace")) - self.assertIn(b"MemoryError", res.out) - def test_does_not_exist(self): cid = _channels.create(REPLACE) with self.assertRaises(_channels.ChannelNotFoundError):