Issue 27783: potential use of unitialized memory in operator.methodcaller (original) (raw)

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 , args=0x37c2d024, kwds=0x0) at ./Modules/_operator.c:956 ...