summaryrefslogtreecommitdiffstats
path: root/Modules/selectmodule.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2013-12-14 17:12:02 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2013-12-14 17:12:02 (GMT)
commit5da107ac7261d8359cd6e1a9a8e57f85176d1180 (patch)
tree171b488800f196c9016ba829cf13abda5f6ee234 /Modules/selectmodule.c
parent01e5f800b40992f2f61f4fd6ac4eca4ae1847cc0 (diff)
downloadcpython-5da107ac7261d8359cd6e1a9a8e57f85176d1180.zip
cpython-5da107ac7261d8359cd6e1a9a8e57f85176d1180.tar.gz
cpython-5da107ac7261d8359cd6e1a9a8e57f85176d1180.tar.bz2
Issue #17919: Fixed integer overflow in the eventmask parameter.
Diffstat (limited to 'Modules/selectmodule.c')
-rw-r--r--Modules/selectmodule.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index 1bccc5f..c492224 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -361,7 +361,7 @@ update_ufd_array(pollObject *self)
assert(i < self->ufd_len);
/* Never overflow */
self->ufds[i].fd = (int)PyLong_AsLong(key);
- self->ufds[i].events = (short)PyLong_AsLong(value);
+ self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
i++;
}
assert(i == self->ufd_len);
@@ -369,6 +369,24 @@ update_ufd_array(pollObject *self)
return 1;
}
+static int
+ushort_converter(PyObject *obj, void *ptr)
+{
+ unsigned long uval;
+
+ uval = PyLong_AsUnsignedLong(obj);
+ if (uval == (unsigned long)-1 && PyErr_Occurred())
+ return 0;
+ if (uval > USHRT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "Python int too large for C unsigned short");
+ return 0;
+ }
+
+ *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
+ return 1;
+}
+
PyDoc_STRVAR(poll_register_doc,
"register(fd [, eventmask] ) -> None\n\n\
Register a file descriptor with the polling object.\n\
@@ -380,12 +398,12 @@ static PyObject *
poll_register(pollObject *self, PyObject *args)
{
PyObject *o, *key, *value;
- int fd, events = POLLIN | POLLPRI | POLLOUT;
+ int fd;
+ unsigned short events = POLLIN | POLLPRI | POLLOUT;
int err;
- if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
+ if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
return NULL;
- }
fd = PyObject_AsFileDescriptor(o);
if (fd == -1) return NULL;
@@ -423,12 +441,12 @@ static PyObject *
poll_modify(pollObject *self, PyObject *args)
{
PyObject *o, *key, *value;
- int fd, events;
+ int fd;
+ unsigned short events;
int err;
- if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
+ if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events))
return NULL;
- }
fd = PyObject_AsFileDescriptor(o);
if (fd == -1) return NULL;
@@ -726,11 +744,11 @@ static PyObject *
internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
{
PyObject *o;
- int fd, events = POLLIN | POLLPRI | POLLOUT;
+ int fd;
+ unsigned short events = POLLIN | POLLPRI | POLLOUT;
- if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
+ if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
return NULL;
- }
fd = PyObject_AsFileDescriptor(o);
if (fd == -1) return NULL;
@@ -746,7 +764,7 @@ internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
}
self->fds[self->n_fds].fd = fd;
- self->fds[self->n_fds].events = events;
+ self->fds[self->n_fds].events = (signed short)events;
if (++self->n_fds == self->max_n_fds) {
if (devpoll_flush(self))