# io.BufferedRWPair doesn't clear its weakrefs on deallocation: # # static void # bufferedrwpair_dealloc(rwpair *self) # { # _PyObject_GC_UNTRACK(self); # Py_CLEAR(self->reader); # Py_CLEAR(self->writer); # Py_CLEAR(self->dict); # Py_TYPE(self)->tp_free((PyObject *) self); # } # # Weakrefs to this object contain stale pointer after BufferedRWPair is freed. # Deleting such a weakref triggers use-after-free: # # Program received signal SIGSEGV, Segmentation fault. # 0x0817b65e in clear_weakref (self=0x40644034) at Objects/weakrefobject.c:56 # 56 PyWeakReference **list = GET_WEAKREFS_LISTPTR(self->wr_object); # (gdb) print *self->wr_object # $1 = {_ob_next = 0xdbdbdbdb, _ob_prev = 0xdbdbdbdb, ob_refcnt = -606348325, # ob_type = 0xdbdbdbdb} # (gdb) bt # #0 0x0817b65e in clear_weakref (self=0x40644034) at Objects/weakrefobject.c:56 # #1 0x0817b815 in weakref_dealloc (self=) # at Objects/weakrefobject.c:106 # #2 0x080f4882 in _Py_Dealloc (op=) at Objects/object.c:1749 import io import weakref fn = "file.txt" w = io.FileIO(fn, "w") r = io.FileIO(fn, "r") brw = io.BufferedRWPair(r,w) ref = weakref.ref(brw) del brw del ref