-
-
Notifications
You must be signed in to change notification settings - Fork 30k
-
-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
elementtree calls PyDict_GetItem without owning a reference to the dict #72133
Comments
I would like to describe an issue in the _elementtree module, and then The issue exists in _elementtree_Element_get_impl in static PyObject *
_elementtree_Element_get_impl(ElementObject *self, PyObject *key,
PyObject *default_value)
{
PyObject* value;
if (...)
value = default_value;
else {
value = PyDict_GetItem(self->extra->attrib, key);
...
}
...
} We look up "key" in the dictionary, that is, in self->extra->attrib. This is We need to hash the "key" object in order to find it in the dictionary. This What happens if the python code gets the dictionary (self->extra->attrib) freed? I've attached a proof-of-concept script which causes a use-after-free through We could fix this by calling Py_INCREF on self->extra->attrib before calling All these bugs could be fixed at once by changing PyDict_GetItem to call Here's a PoC for the _elementtree module. --- begin script --- import _elementtree as et
state = {
"tag": "tag",
"_children": [],
"attrib": "attr",
"tail": "tail",
"text": "text",
}
class X:
def __hash__(self):
e.__setstate__(state) # this frees e->extra->attrib
return 13
e = et.Element("elem", {1: 2})
e.get(X()) --- end script --- Running it (64-bits Python 3.5.2, --with-pydebug) causes a use-after-free with (gdb) r ./poc13.py Program received signal SIGSEGV, Segmentation fault. |
Verified problem. Added patch to keep reference to dict in PyDict_GetItem. |
Added test to patch |
This is a bug in elementtree - the caller should own a reference to the dict during the entire PyDict_GetItem call. We won't add the refcount change you propose because it's not free and this is a hot function. The test in your patch doesn't fail for me (I tried on version 3.11 on a Mac). Are you still seeing the problem on version >= 3.9, or perhaps it was fixed in eaementtree by now? |
Concur with Irit. We should patch the caller of PyDict_GetItem, not PyDict_GetItem. |
The issue is no longer reproduced by the original test because of the cache for dict key tables. But it is not gone, and can be reproduced with modified test. There may be many similar bugs in the Python core end extensions. Adding incref/decref in PyDict_GetItem and similar C API functions could fix many of them, but perhaps not all, and it would hit performance. I suppose modt of uses of PyDict_GetItem are safe. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: