Skip to content

Commit f005765

Browse files
[3.15] gh-143376: validate usages of _interpchannels.ChannelID in _channelid_shared (GH-146574) (#159995)
gh-143376: validate usages of `_interpchannels.ChannelID` in `_channelid_shared` (GH-146574) (cherry picked from commit c6a084a) Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
1 parent 9ce74c5 commit f005765

3 files changed

Lines changed: 47 additions & 1 deletion

File tree

‎Lib/test/test_interpreters/test_channels.py‎

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# Raise SkipTest if subinterpreters not supported.
1010
_channels = import_helper.import_module('_interpchannels')
1111
from concurrent import interpreters
12-
from test.support import channels
12+
from test.support import channels, force_not_colorized
1313
from .utils import _run_output, TestBase
1414

1515

@@ -30,6 +30,39 @@ def test_highlevel_reloaded(self):
3030
# See gh-115490 (https://github.com/python/cpython/issues/115490).
3131
importlib.reload(channels)
3232

33+
@force_not_colorized
34+
def test_channel_id_types(self):
35+
# See https://github.com/python/cpython/issues/143376.
36+
code = """\
37+
import _interpchannels
38+
import re
39+
from concurrent import interpreters
40+
41+
class End:
42+
__slots__ = ()
43+
def __new__(cls, chan=None):
44+
return object.__new__(cls)
45+
@property
46+
def _id(self):
47+
return object()
48+
49+
class Send(End): pass
50+
class Recv(End): pass
51+
52+
_interpchannels._register_end_types(Send, Recv)
53+
chan = _interpchannels._channel_id(_interpchannels.create(), _resolve=True)
54+
interp = interpreters.create()
55+
try:
56+
interp.prepare_main(chan=Send(chan))
57+
finally:
58+
interp.close()
59+
"""
60+
61+
out, err = self.assert_python_failure("-c", code)
62+
self.assertEqual(out, '')
63+
errmsg = "TypeError: '_id' attribute must be an _interpchannels.ChannelID object, not object"
64+
self.assertIn(errmsg, err)
65+
3366

3467
class TestChannels(TestBase):
3568

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`concurrent.interpreters`: fix a crash when internal cross-interpreter
2+
channel ends have incorrect channel IDs. Patch by Bénédikt Tran.

‎Modules/_interpchannelsmodule.c‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2634,6 +2634,17 @@ _channelid_from_xid(_PyXIData_t *data)
26342634
static int
26352635
_channelid_shared(PyThreadState *tstate, PyObject *obj, _PyXIData_t *data)
26362636
{
2637+
module_state *st = _get_current_module_state();
2638+
if (st == NULL) {
2639+
return -1;
2640+
}
2641+
if (!PyObject_IsInstance(obj, (PyObject *)st->ChannelIDType)) {
2642+
PyErr_Format(PyExc_TypeError,
2643+
"'_id' attribute must be an %N object, not %T",
2644+
st->ChannelIDType, obj);
2645+
return -1;
2646+
}
2647+
26372648
if (_PyXIData_InitWithSize(
26382649
data, tstate->interp, sizeof(struct _channelid_xid), obj,
26392650
_channelid_from_xid

0 commit comments

Comments
 (0)