-
-
Notifications
You must be signed in to change notification settings - Fork 34.2k
Closed
Labels
3.13bugs and security fixesbugs and security fixes3.14bugs and security fixesbugs and security fixes3.15new features, bugs and security fixesnew features, bugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump
Description
Crash report
What happened?
It's possible to segfault the interpreter by corrupting a set, then calling repr() on it.
MRE:
tasks = set()
class Dummy(object):
def __hash__(self):
return 0
class CorrupTrigger():
counter = 0
def __hash__(self):
return 0
def __eq__(self,other):
if self.counter < 1:
self.counter += 1
tasks.add(self)
return False
tasks.add(Dummy())
tasks.add(Dummy())
tasks.pop()
tasks.add(CorrupTrigger())
repr(tasks)Backtrace:
Program received signal SIGSEGV, Segmentation fault.
0x0000555555b5b1e7 in Py_INCREF (op=0x0) at ./Include/refcount.h:281
281 PY_UINT32_T cur_refcnt = op->ob_refcnt;
(gdb) bt
#0 0x0000555555b5b1e7 in Py_INCREF (op=0x0) at ./Include/refcount.h:281
#1 _Py_NewRef (obj=0x0) at ./Include/refcount.h:529
#2 list_repr_impl (v=0x7c6ff6e72f60) at Objects/listobject.c:598
#3 list_repr (self=0x7c6ff6e72f60) at Objects/listobject.c:638
#4 0x0000555555bea219 in PyObject_Repr (v=v@entry=0x7c6ff6e72f60) at Objects/object.c:779
#5 0x0000555555c3c4b7 in set_repr_lock_held (so=0x7d0ff6eb17a0) at Objects/setobject.c:594
#6 set_repr (self=0x7d0ff6eb17a0) at Objects/setobject.c:622
#7 0x0000555555bea219 in PyObject_Repr (v=0x7d0ff6eb17a0) at Objects/object.c:779
#8 0x0000555555bd9b13 in cfunction_vectorcall_O (func=func@entry=0x7c7ff6e35d40, args=args@entry=0x7bfff5f70208, nargsf=nargsf@entry=9223372036854775809, kwnames=kwnames@entry=0x0)
at Objects/methodobject.c:536
#9 0x0000555555aba6a0 in _PyObject_VectorcallTstate (tstate=0x555556aebf00 <_PyRuntime+358560>, callable=0x7c7ff6e35d40, args=0x7bfff5f70208, nargsf=9223372036854775809, kwnames=0x0)
at ./Include/internal/pycore_call.h:169
#10 0x0000555555e8cf61 in _PyEval_EvalFrameDefault (tstate=<optimized out>, frame=<optimized out>, throwflag=<optimized out>) at Python/generated_cases.c.h:1620
#11 0x0000555555e4a67b in _PyEval_EvalFrame (tstate=0x555556aebf00 <_PyRuntime+358560>, frame=0x7e8ff6de5220, throwflag=0) at ./Include/internal/pycore_ceval.h:121
It's also possible to get set_pop_impl into an infinite loop by changing the last code block to:
tasks.add(Dummy())
tasks.add(Dummy())
tasks.pop()
tasks.add(CorrupTrigger())
tasks.pop()
tasks.pop()
tasks.pop()Found when trying to simplify the MRE in #139071.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
Python 3.15.0a2+ (heads/main-dirty:41b9ad5b38e, Nov 20 2025, 11:03:41) [Clang 21.1.2 (2ubuntu6)]
Linked PRs
- gh-141805: avoid increase the set->used twice when the __eq__ trigger another add #142007
- gh-141805: Fix crash after concurrent addition objects with the same hash to set #143815
- [3.14] gh-141805: Fix crash after concurrent addition objects with the same hash to set (GH-143815) #143849
- [3.13] gh-141805: Fix crash after concurrent addition objects with the same hash to set (GH-143815) #143853
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
3.13bugs and security fixesbugs and security fixes3.14bugs and security fixesbugs and security fixes3.15new features, bugs and security fixesnew features, bugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump