Open
Description
Crash report
The implementation of PyDict_Clear()
isn't safe for dictionaries with values that are embedded in an object:
The calls to Py_CLEAR(oldvalues->values[i])
can execute arbitrary code via object destructors. oldvalues
may no longer be valid because the object its embedded in may be freed during the Py_CLEAR()
call.
Lines 2868 to 2880 in 0ef4ffe
Repro
./configure --with-address-sanitizer --with-pydebug --without-pymalloc
class MyObj:
pass
class DelXOnDelete:
def __del__(self):
global x
del x
x = MyObj()
x.a = DelXOnDelete()
d = x.__dict__
d.clear()
==3794958==ERROR: AddressSanitizer: heap-use-after-free on address 0x513000022ec2 at pc 0x56320dddb439 bp 0x7fff8205bb90 sp 0x7fff8205bb88
READ of size 1 at 0x513000022ec2 thread T0
#0 0x56320dddb438 in clear_lock_held /raid/sgross/cpython/Objects/dictobject.c:2872:24
#1 0x56320dddb438 in PyDict_Clear /raid/sgross/cpython/Objects/dictobject.c:2889:5
#2 0x56320ddf7e38 in dict_clear_impl /raid/sgross/cpython/Objects/dictobject.c:4452:5
#3 0x56320ddf7e38 in dict_clear /raid/sgross/cpython/Objects/clinic/dictobject.c.h:157:12
...
freed by thread T0 here:
#0 0x56320db400e6 in free (/raid/sgross/cpython/python+0x2fd0e6) (BuildId: f9a13329ff2de3d6fd6a01eae843cc226d0d8f7c)
#1 0x56320de99e6a in subtype_dealloc /raid/sgross/cpython/Objects/typeobject.c:2611:5
#2 0x56320de31448 in _Py_Dealloc /raid/sgross/cpython/Objects/object.c:3004:5
#3 0x56320dddc0e6 in Py_DECREF /raid/sgross/cpython/./Include/refcount.h:393:9
#4 0x56320dddc0e6 in _PyDict_Pop_KnownHash /raid/sgross/cpython/Objects/dictobject.c:3028:9
#5 0x56320e064bd4 in _PyEval_EvalFrameDefault /raid/sgross/cpython/Python/generated_cases.c.h:5006:23
...