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
chain.__setstate__ Type Confusion #72509
Comments
Python 3.5.2 suffers from a type confusion vulnerability in the chain.__setstate__ method of the itertools module. The issue exists due to lack of argument validation in the chain_setstate() function: static PyObject *
chain_setstate(chainobject *lz, PyObject *state)
{
PyObject *source, *active=NULL;
Py_INCREF(source);
Py_XSETREF(lz->source, source);
Py_XINCREF(active);
Py_XSETREF(lz->active, active);
Py_RETURN_NONE;
} After parsing the argument tuple, source and active are set without validating that they are iterator objects. This causes issues elsewhere, where the values are passed PyIter_Next: static PyObject *
chain_next(chainobject *lz)
{
PyObject *item;
if (lz->active == NULL) {
PyObject *iterable = PyIter_Next(lz->source);
if (iterable == NULL) {
Py_CLEAR(lz->source);
return NULL; /* no more input sources */
}
lz->active = PyObject_GetIter(iterable);
Py_DECREF(iterable);
if (lz->active == NULL) {
Py_CLEAR(lz->source);
return NULL; /* input not iterable */
}
}
item = PyIter_Next(lz->active);
if (item != NULL)
return item;
if (PyErr_Occurred()) {
if (PyErr_ExceptionMatches(PyExc_StopIteration))
PyErr_Clear();
else
return NULL; /* input raised an exception */
}
Py_CLEAR(lz->active);
return chain_next(lz); /* recurse and use next active */
} In some cases, this can lead to a DEP access violation. It might be possible to exploit this to achieve code execution. (4074.198c): Access violation - code c0000005 (first chance) To fix this issue, it is recommended that chain_setstate() be updated to validate its arguments. A proposed patch has been attached. static PyObject *
chain_setstate(chainobject *lz, PyObject *state)
{
PyObject *source, *active=NULL;
if (!PyIter_Check(source) || (active != NULL && !PyIter_Check(active))) {
PyErr_SetString(PyExc_ValueError, "Arguments must be iterators.");
return NULL;
}
Py_INCREF(source);
Py_XSETREF(lz->source, source);
Py_XINCREF(active);
Py_XSETREF(lz->active, active);
Py_RETURN_NONE;
} |
There is similar issue with itertools.cycle(). And leaking SystemError to user code should be considered as a bug. Proposed patch fixes these issues. |
The patch looks reasonable. |
New changeset 258ebc539b2e by Serhiy Storchaka in branch '3.5': New changeset c4937d066a8e by Serhiy Storchaka in branch '3.6': New changeset cb0755aa9f3d by Serhiy Storchaka in branch 'default': |
Thank you for your contribution John. cycle.__setstate__() was fixed in a4d5ef7fdec3 in 3.6, but the fix was not backported to 3.5. There is no pickle support in 2.7. |
Misc/NEWS
so that it is managed by towncrier #552Note: 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: