This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: potential use of unitialized memory in operator.methodcaller
Type: crash Stage: resolved
Components: Library (Lib) Versions: Python 3.6, Python 3.2, Python 3.3, Python 3.4, Python 3.5, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: benjamin.peterson, python-dev
Priority: normal Keywords:

Created on 2016-08-17 06:32 by benjamin.peterson, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (2)
msg272904 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2016-08-17 06:32
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
...
msg272905 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2016-08-17 06:38
New changeset 11a9bca71528 by Benjamin Peterson in branch '2.7':
rearrange methodcaller_new so that the main error case does not cause uninitialized memory usage (closes #27783)
https://hg.python.org/cpython/rev/11a9bca71528

New changeset 8e3b9bf917a7 by Benjamin Peterson in branch '3.3':
rearrange methodcaller_new so that the main error case does not cause uninitialized memory usage (closes #27783)
https://hg.python.org/cpython/rev/8e3b9bf917a7

New changeset 675e20c38fda by Benjamin Peterson in branch '3.4':
merge 3.3 (#27783)
https://hg.python.org/cpython/rev/675e20c38fda

New changeset d1b93ce7dad8 by Benjamin Peterson in branch '3.5':
merge 3.4 (#27783)
https://hg.python.org/cpython/rev/d1b93ce7dad8

New changeset 0f0a040d45b2 by Benjamin Peterson in branch 'default':
merge 3.5 (#27783)
https://hg.python.org/cpython/rev/0f0a040d45b2
History
Date User Action Args
2022-04-11 14:58:34adminsetgithub: 71970
2016-08-17 06:38:01python-devsetstatus: open -> closed

nosy: + python-dev
messages: + msg272905

resolution: fixed
stage: resolved
2016-08-17 06:32:24benjamin.petersoncreate