Skip to content

Commit

Permalink
pythongh-115874: Don't use module state in teedataobject tp_dealloc (p…
Browse files Browse the repository at this point in the history
…ythonGH-116204)

(cherry picked from commit e2fcaf1)

Co-authored-by: Erlend E. Aasland <erlend@python.org>
Co-authored-by: Brandt Bucher <brandtbucher@microsoft.com>
  • Loading branch information
2 people authored and miss-islington committed Mar 18, 2024
1 parent 25243b1 commit fb64bb0
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 6 deletions.
10 changes: 9 additions & 1 deletion Lib/test/test_itertools.py
@@ -1,7 +1,7 @@
import doctest
import unittest
from test import support
from test.support import threading_helper
from test.support import threading_helper, script_helper
from itertools import *
import weakref
from decimal import Decimal
Expand Down Expand Up @@ -1695,6 +1695,14 @@ def test_tee(self):
self.pickletest(proto, a, compare=ans)
self.pickletest(proto, b, compare=ans)

def test_tee_dealloc_segfault(self):
# gh-115874: segfaults when accessing module state in tp_dealloc.
script = (
"import typing, copyreg, itertools; "
"copyreg.buggy_tee = itertools.tee(())"
)
script_helper.assert_python_ok("-c", script)

# Issue 13454: Crash when deleting backward iterator from tee()
def test_tee_del_backward(self):
forward, backward = tee(repeat(None, 20000000))
Expand Down
8 changes: 3 additions & 5 deletions Modules/itertoolsmodule.c
Expand Up @@ -810,10 +810,9 @@ teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
}

static void
teedataobject_safe_decref(PyObject *obj, PyTypeObject *tdo_type)
teedataobject_safe_decref(PyObject *obj)
{
while (obj && Py_IS_TYPE(obj, tdo_type) &&
Py_REFCNT(obj) == 1) {
while (obj && Py_REFCNT(obj) == 1) {
PyObject *nextlink = ((teedataobject *)obj)->nextlink;
((teedataobject *)obj)->nextlink = NULL;
Py_SETREF(obj, nextlink);
Expand All @@ -832,8 +831,7 @@ teedataobject_clear(teedataobject *tdo)
Py_CLEAR(tdo->values[i]);
tmp = tdo->nextlink;
tdo->nextlink = NULL;
itertools_state *state = get_module_state_by_cls(Py_TYPE(tdo));
teedataobject_safe_decref(tmp, state->teedataobject_type);
teedataobject_safe_decref(tmp);
return 0;
}

Expand Down

0 comments on commit fb64bb0

Please sign in to comment.