14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm""" 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThe gc module can still invoke arbitrary Python code and crash. 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThis is an attack against _PyInstance_Lookup(), which is documented 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmas follows: 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The point of this routine is that it never calls arbitrary Python 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm code, so is always "safe": all it does is dict lookups. 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBut of course dict lookups can call arbitrary Python code. 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThe following code causes mutation of the object graph during 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmthe call to has_finalizer() in gcmodule.c, and that might 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmsegfault. 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm""" 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport gc 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass A: 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __hash__(self): 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return hash("__del__") 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __eq__(self, other): 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del self.other 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return False 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylma = A() 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmb = A() 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylma.__dict__[b] = 'A' 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylma.other = b 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmb.other = a 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmgc.collect() 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdel a, b 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmgc.collect() 37