diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2017-10-12 20:20:44 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2017-10-12 20:20:44 (GMT) |
commit | c923da188bc055e4f3001a6daf1caf54f2b10e40 (patch) | |
tree | a149e97942c1f48a9f846559b70ff650b6634e12 /Modules/selectmodule.c | |
parent | f8d42ea0e4341b270f1de71b4ff40cfa18420eed (diff) | |
download | cpython-c923da188bc055e4f3001a6daf1caf54f2b10e40.zip cpython-c923da188bc055e4f3001a6daf1caf54f2b10e40.tar.gz cpython-c923da188bc055e4f3001a6daf1caf54f2b10e40.tar.bz2 |
[3.6] bpo-30058: Fixed buffer overflow in select.kqueue.control(). (GH-1095) (#3973)
(cherry picked from commit de072100775cc29e6cd93a75466cecbd1086f258)
Diffstat (limited to 'Modules/selectmodule.c')
-rw-r--r-- | Modules/selectmodule.c | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 07a20c8..4a7fe00 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -2103,7 +2103,7 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) int i = 0; PyObject *otimeout = NULL; PyObject *ch = NULL; - PyObject *it = NULL, *ei = NULL; + PyObject *seq = NULL, *ei = NULL; PyObject *result = NULL; struct kevent *evl = NULL; struct kevent *chl = NULL; @@ -2149,37 +2149,34 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) } if (ch != NULL && ch != Py_None) { - it = PyObject_GetIter(ch); - if (it == NULL) { - PyErr_SetString(PyExc_TypeError, - "changelist is not iterable"); + seq = PySequence_Fast(ch, "changelist is not iterable"); + if (seq == NULL) { return NULL; } - nchanges = PyObject_Size(ch); - if (nchanges < 0) { + if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "changelist is too long"); goto error; } + nchanges = (int)PySequence_Fast_GET_SIZE(seq); chl = PyMem_New(struct kevent, nchanges); if (chl == NULL) { PyErr_NoMemory(); goto error; } - i = 0; - while ((ei = PyIter_Next(it)) != NULL) { + for (i = 0; i < nchanges; ++i) { + ei = PySequence_Fast_GET_ITEM(seq, i); if (!kqueue_event_Check(ei)) { - Py_DECREF(ei); PyErr_SetString(PyExc_TypeError, "changelist must be an iterable of " "select.kevent objects"); goto error; - } else { - chl[i++] = ((kqueue_event_Object *)ei)->e; } - Py_DECREF(ei); + chl[i] = ((kqueue_event_Object *)ei)->e; } + Py_CLEAR(seq); } - Py_CLEAR(it); /* event list */ if (nevents) { @@ -2247,7 +2244,7 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) PyMem_Free(chl); PyMem_Free(evl); Py_XDECREF(result); - Py_XDECREF(it); + Py_XDECREF(seq); return NULL; } @@ -2255,7 +2252,7 @@ PyDoc_STRVAR(kqueue_queue_control_doc, "control(changelist, max_events[, timeout=None]) -> eventlist\n\ \n\ Calls the kernel kevent function.\n\ -- changelist must be a list of kevent objects describing the changes\n\ +- changelist must be an iterable of kevent objects describing the changes\n\ to be made to the kernel's watch list or None.\n\ - max_events lets you specify the maximum number of events that the\n\ kernel will return.\n\ |