Skip to content

Missing error checks in termios module #110260

Closed
@sobolevn

Description

@sobolevn

Bug report

There are multiple cases where PyList_SetItem does not check for -1 in termios module. We need to fix this. There are two options to fix this:

  • < 0 check
  • PyList_SET_ITEM usage

There are two possible errors that PyList_SetItem can produce:

    if (!PyList_Check(op)) {
        Py_XDECREF(newitem);
        PyErr_BadInternalCall();
        return -1;
    }
    if (!valid_index(i, Py_SIZE(op))) {
        Py_XDECREF(newitem);
        PyErr_SetString(PyExc_IndexError,
                        "list assignment index out of range");
        return -1;
    }

Each case needs an explanation.

cpython/Modules/termios.c

Lines 116 to 124 in 8c07137

PyObject *v;
int i;
for (i = 0; i < NCCS; i++) {
char ch = (char)mode.c_cc[i];
v = PyBytes_FromStringAndSize(&ch, 1);
if (v == NULL)
goto err;
PyList_SetItem(cc, i, v);
}

Here cc is always a list and i goes from 0 to some other int value by i++, it is safe to use PyList_SET_ITEM.

cpython/Modules/termios.c

Lines 129 to 137 in 8c07137

if ((mode.c_lflag & ICANON) == 0) {
v = PyLong_FromLong((long)mode.c_cc[VMIN]);
if (v == NULL)
goto err;
PyList_SetItem(cc, VMIN, v);
v = PyLong_FromLong((long)mode.c_cc[VTIME]);
if (v == NULL)
goto err;
PyList_SetItem(cc, VTIME, v);

Here cc is a list, but VMIN and VTIME are 3rd party constants from termios.h. I guess it is safer to use explicit error check.

cpython/Modules/termios.c

Lines 140 to 153 in 8c07137

if (!(v = PyList_New(7)))
goto err;
PyList_SetItem(v, 0, PyLong_FromLong((long)mode.c_iflag));
PyList_SetItem(v, 1, PyLong_FromLong((long)mode.c_oflag));
PyList_SetItem(v, 2, PyLong_FromLong((long)mode.c_cflag));
PyList_SetItem(v, 3, PyLong_FromLong((long)mode.c_lflag));
PyList_SetItem(v, 4, PyLong_FromLong((long)ispeed));
PyList_SetItem(v, 5, PyLong_FromLong((long)ospeed));
if (PyErr_Occurred()) {
Py_DECREF(v);
goto err;
}
PyList_SetItem(v, 6, cc);

Here we need to check for possibel PyLong_FromLong error, but we can use PyList_SET_ITEM.

Linked PRs

Metadata

Metadata

Assignees

Labels

extension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions