Author Oren Milman
Recipients Oren Milman, geeknik
Date 2017-10-06.09:49:18
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1507283359.28.0.213398074469.issue31165@psf.upfronthosting.co.za>
In-reply-to
Content
Here is some similar code that crashes for the same reasons:

# create a circular reference with a malicious __del__().
class A:
    def __del__(*args):
        del list1[0]
circ_ref_obj = A()
circ_ref_obj._self = circ_ref_obj

list1 = [None]
list2 = []
del circ_ref_obj
while len(list2) < 10000:
    list2.append(list1[:])

IIUC, list_slice() first finds the boundaries of the slice and its length, and
then calls PyList_New().
But PyList_New() might call PyObject_GC_New(), which eventually causes a call
to _PyObject_GC_Alloc(), which might call collect_generations(), which causes
the malicious __del__() to run.
After __del__() empties the list, list_slice() continues to run, but the list's
boundaries it found earlier are now invalid, and so it tries to read the first
element in the now empty list, and crashes.


Maybe we should prevent collection of garbage with circular references (that
has __del__() or weakref callbacks) from PyObject_GC_New()?

ISTM there might be a lot of places with similar issues. (e.g. if we replace
'list2.append(list1[:])' with 'list2.append(list1[::-1])', we get a crash in
list_subscript()).
So i think that fixing each of them would be harder and might even introduce a
regression in performance.
History
Date User Action Args
2017-10-06 09:49:19Oren Milmansetrecipients: + Oren Milman, geeknik
2017-10-06 09:49:19Oren Milmansetmessageid: <1507283359.28.0.213398074469.issue31165@psf.upfronthosting.co.za>
2017-10-06 09:49:19Oren Milmanlinkissue31165 messages
2017-10-06 09:49:18Oren Milmancreate