Issue #17919: Fixed integer overflow in the eventmask parameter.

This commit is contained in:
Serhiy Storchaka 2013-12-14 19:18:39 +02:00
commit 03241e8017
4 changed files with 50 additions and 17 deletions

View file

@ -356,7 +356,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);
@ -364,6 +364,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\
@ -375,12 +393,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;
@ -418,12 +436,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;
@ -728,14 +746,14 @@ 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 (self->fd_devpoll < 0)
return devpoll_err_closed();
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;
@ -751,7 +769,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))