]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-152635: Raise MemoryError when the lock allocation fails in `_interpchannels.creat...
authorSteve Stagg <stestagg@gmail.com>
Tue, 30 Jun 2026 10:57:28 +0000 (11:57 +0100)
committerGitHub <noreply@github.com>
Tue, 30 Jun 2026 10:57:28 +0000 (13:57 +0300)
Previously, an allocation failure when creating
the lock for a channel in `_interpchannels` would trigger an assert.
Caused by `handle_channel_error` being passed an error code of -1
which is only allowed if an exception has been set.
(in this case, no exception was set)

`channelsmod_create` now forwards the error code from `channel_create`
which `handle_channel_error` already handled.

Co-authored-by: sobolevn <mail@sobolevn.me>
Misc/NEWS.d/next/Core_and_Builtins/2026-06-29-23-29-14.gh-issue-152635.O21J0O.rst [new file with mode: 0644]
Modules/_interpchannelsmodule.c

diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-29-23-29-14.gh-issue-152635.O21J0O.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-29-23-29-14.gh-issue-152635.O21J0O.rst
new file mode 100644 (file)
index 0000000..dadb25f
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a crash caused when running out of memory creating a
+:mod:`!_interpchannels` channel. Now a :exc:`MemoryError` is correctly raised.
index 05957081079d4a06dbe6488ad5a4dd68edc34a86..358d51cf13f1afae16592313ba877ee2f60091b1 100644 (file)
@@ -354,7 +354,7 @@ clear_module_state(module_state *state)
 #define ERR_CHANNEL_INTERP_CLOSED -4
 #define ERR_CHANNEL_EMPTY -5
 #define ERR_CHANNEL_NOT_EMPTY -6
-#define ERR_CHANNEL_MUTEX_INIT -7
+#define ERR_CHANNEL_MUTEX_INIT -7  // currently unused
 #define ERR_CHANNELS_MUTEX_INIT -8
 #define ERR_NO_NEXT_CHANNEL_ID -9
 #define ERR_CHANNEL_CLOSED_WAITING -10
@@ -427,10 +427,6 @@ handle_channel_error(int err, PyObject *mod, int64_t cid)
                      "if not empty (try force=True)",
                      cid);
     }
-    else if (err == ERR_CHANNEL_MUTEX_INIT) {
-        PyErr_SetString(state->ChannelError,
-                        "can't initialize mutex for new channel");
-    }
     else if (err == ERR_CHANNELS_MUTEX_INIT) {
         PyErr_SetString(state->ChannelError,
                         "can't initialize mutex for channel management");
@@ -1744,7 +1740,8 @@ channel_create(_channels *channels, struct _channeldefaults defaults)
 {
     PyThread_type_lock mutex = PyThread_allocate_lock();
     if (mutex == NULL) {
-        return ERR_CHANNEL_MUTEX_INIT;
+        PyErr_NoMemory();
+        return -1;
     }
     _channel_state *chan = _channel_new(mutex, defaults);
     if (chan == NULL) {
@@ -2938,7 +2935,7 @@ channelsmod_create(PyObject *self, PyObject *args, PyObject *kwds)
 
     int64_t cid = channel_create(&_globals.channels, defaults);
     if (cid < 0) {
-        (void)handle_channel_error(-1, self, cid);
+        (void)handle_channel_error(cid, self, cid);
         return NULL;
     }
     module_state *state = get_module_state(self);