[New-bugs-announce] [issue27462] NULL Pointer deref in binary_iop1 function

Emin Ghuliev report at bugs.python.org
Thu Jul 7 11:48:13 EDT 2016


New submission from Emin Ghuliev:

Python VM parses "0x3b" opcode (INPLACE_MODULO) in the bytecode file. Subsequently VM parses left and right arguments of the opcode (0x3b). If left and right arguments doesn't exists in the bytecode file that causes a segmentation fault. Which triggered by the binary_iop1 function.


PyEval_EvalFrameEx() at Python/ceval.c:1749

        TARGET(INPLACE_MODULO) {
            PyObject *right = POP();
            PyObject *left = TOP();
            PyObject *mod = PyNumber_InPlaceRemainder(left, right); < left = 0, right = 0;

Then INPLACE_MODULO opcode is passed two arguments into PyNumber_InPlaceRemainder. However, in order to call the binary_iop:

PyNumber_InPlaceRemainder at Objects/abstract.c:1102

PyNumber_InPlaceRemainder(PyObject *v, PyObject *w)
{
    return binary_iop(v, w, NB_SLOT(nb_inplace_remainder),
                            NB_SLOT(nb_remainder), "%=");
}

Subsequently the binary_iop function is passed "v" argument into the binary_iop1:

binary_iop at Objects/abstract.c:1005

static PyObject *
binary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot,
                const char *op_name)
{
    PyObject *result = binary_iop1(v, w, iop_slot, op_slot); # v = 0 and call the binary_iop1 function
    if (result == Py_NotImplemented) {
        Py_DECREF(result);
        return binop_type_error(v, w, op_name);
    }
    return result;
}

binary_iop1 at Objects/abstract.c:988

static PyObject *
binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot)
{
    PyNumberMethods *mv = v->ob_type->tp_as_number; // dereference object < -- > v = 0x0
    if (mv != NULL) {
        binaryfunc slot = NB_BINOP(mv, iop_slot);
        if (slot) {
            PyObject *x = (slot)(v, w);
            if (x != Py_NotImplemented) {
                return x;
            }
            Py_DECREF(x);
        }
    }
    return binary_op1(v, w, op_slot);
}

The binary_iop1 function doesn't check "v" field and dereference it.

<PyNumber_InPlaceRemainder+16>  mov    rsi,QWORD PTR [rdi+0x8] = 0x8 byte -> ob_type 

$rdi register = 0x0


Program received signal SIGSEGV, Segmentation fault.

----------
components: Interpreter Core
files: repro
messages: 269940
nosy: Emin Ghuliev
priority: normal
severity: normal
status: open
title: NULL Pointer deref in binary_iop1 function
versions: Python 3.6
Added file: http://bugs.python.org/file43654/repro

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue27462>
_______________________________________


More information about the New-bugs-announce mailing list