Skip to content

Commit faef7f1

Browse files
gh-146065: Fix NULL dereference in FutureIter_am_send
1 parent 1b11835 commit faef7f1

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

Lib/test/test_asyncio/test_futures.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,21 @@ def test_future_disallow_multiple_initialization(self):
755755
with self.assertRaises(RuntimeError, msg="is already initialized"):
756756
f.__init__(loop=self.loop)
757757

758+
def test_futureiter_send_after_throw_no_crash(self):
759+
async def exploit():
760+
loop = asyncio.get_event_loop()
761+
fut = loop.create_future()
762+
it = fut.__await__()
763+
it.__next__()
764+
try:
765+
it.throw(RuntimeError)
766+
except RuntimeError:
767+
pass
768+
with self.assertRaises(StopIteration):
769+
it.send(None)
770+
asyncio.run(exploit())
771+
772+
758773
@unittest.skipUnless(hasattr(futures, '_CFuture'),
759774
'requires the C _asyncio module')
760775
class CFutureTests(BaseFutureTests, test_utils.TestCase):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a NULL pointer dereference in asyncio.Future iterator when send() is
2+
called after throw() or close(), which previously could cause a crash.

Modules/_asynciomodule.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,6 +1872,11 @@ FutureIter_am_send(PyObject *op,
18721872
PyObject **result)
18731873
{
18741874
futureiterobject *it = (futureiterobject*)op;
1875+
if (it->future == NULL) {
1876+
PyErr_SetNone(PyExc_StopIteration);
1877+
*result = NULL;
1878+
return PYGEN_RETURN;
1879+
}
18751880
/* arg is unused, see the comment on FutureIter_send for clarification */
18761881
PySendResult res;
18771882
Py_BEGIN_CRITICAL_SECTION(it->future);

0 commit comments

Comments
 (0)