mirror of https://github.com/python/cpython.git
gh-111178: fix UBSan failures in `Modules/selectmodule.c` (GH-129792)
Fix some UBSan failures for `pollObject`, `devpollObject`, `pyEpoll_Object` as well as for `kqueue_event_Object`, `kqueue_queue_Object` and `kqueue_tracking_after_fork`. Suppress unused return values. Rename the unused parameter in `METH_NOARGS` and getter/setter methods to `dummy` and `closure` respectively for semantic purposes. Explicitly declare `_select_exec` as a `static` function.
This commit is contained in:
parent
de13293d26
commit
73bbaf33ae
|
@ -439,6 +439,8 @@ typedef struct {
|
|||
int poll_running;
|
||||
} pollObject;
|
||||
|
||||
#define pollObject_CAST(op) ((pollObject *)(op))
|
||||
|
||||
/* Update the malloc'ed array of pollfds to match the dictionary
|
||||
contained within a pollObject. Return 1 on success, 0 on an error.
|
||||
*/
|
||||
|
@ -772,11 +774,13 @@ newPollObject(PyObject *module)
|
|||
}
|
||||
|
||||
static void
|
||||
poll_dealloc(pollObject *self)
|
||||
poll_dealloc(PyObject *op)
|
||||
{
|
||||
PyObject* type = (PyObject *)Py_TYPE(self);
|
||||
if (self->ufds != NULL)
|
||||
pollObject *self = pollObject_CAST(op);
|
||||
PyTypeObject *type = Py_TYPE(self);
|
||||
if (self->ufds != NULL) {
|
||||
PyMem_Free(self->ufds);
|
||||
}
|
||||
Py_XDECREF(self->dict);
|
||||
PyObject_Free(self);
|
||||
Py_DECREF(type);
|
||||
|
@ -794,6 +798,8 @@ typedef struct {
|
|||
struct pollfd *fds;
|
||||
} devpollObject;
|
||||
|
||||
#define devpollObject_CAST(op) ((devpollObject *)(op))
|
||||
|
||||
static PyObject *
|
||||
devpoll_err_closed(void)
|
||||
{
|
||||
|
@ -1086,13 +1092,14 @@ select_devpoll_close_impl(devpollObject *self)
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
|
||||
static PyObject *
|
||||
devpoll_get_closed(PyObject *op, void *Py_UNUSED(closure))
|
||||
{
|
||||
if (self->fd_devpoll < 0)
|
||||
devpollObject *self = devpollObject_CAST(op);
|
||||
if (self->fd_devpoll < 0) {
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
|
@ -1112,7 +1119,7 @@ select_devpoll_fileno_impl(devpollObject *self)
|
|||
}
|
||||
|
||||
static PyGetSetDef devpoll_getsetlist[] = {
|
||||
{"closed", (getter)devpoll_get_closed, NULL,
|
||||
{"closed", devpoll_get_closed, NULL,
|
||||
"True if the devpoll object is closed"},
|
||||
{0},
|
||||
};
|
||||
|
@ -1163,9 +1170,10 @@ newDevPollObject(PyObject *module)
|
|||
}
|
||||
|
||||
static void
|
||||
devpoll_dealloc(devpollObject *self)
|
||||
devpoll_dealloc(PyObject *op)
|
||||
{
|
||||
PyObject *type = (PyObject *)Py_TYPE(self);
|
||||
devpollObject *self = devpollObject_CAST(op);
|
||||
PyTypeObject *type = Py_TYPE(self);
|
||||
(void)devpoll_internal_close(self);
|
||||
PyMem_Free(self->fds);
|
||||
PyObject_Free(self);
|
||||
|
@ -1275,6 +1283,8 @@ typedef struct {
|
|||
SOCKET epfd; /* epoll control file descriptor */
|
||||
} pyEpoll_Object;
|
||||
|
||||
#define pyEpoll_Object_CAST(op) ((pyEpoll_Object *)(op))
|
||||
|
||||
static PyObject *
|
||||
pyepoll_err_closed(void)
|
||||
{
|
||||
|
@ -1377,13 +1387,14 @@ select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
|
|||
|
||||
|
||||
static void
|
||||
pyepoll_dealloc(pyEpoll_Object *self)
|
||||
pyepoll_dealloc(PyObject *op)
|
||||
{
|
||||
PyTypeObject* type = Py_TYPE(self);
|
||||
pyEpoll_Object *self = pyEpoll_Object_CAST(op);
|
||||
PyTypeObject *type = Py_TYPE(self);
|
||||
(void)pyepoll_internal_close(self);
|
||||
freefunc epoll_free = PyType_GetSlot(type, Py_tp_free);
|
||||
epoll_free((PyObject *)self);
|
||||
Py_DECREF((PyObject *)type);
|
||||
epoll_free(self);
|
||||
Py_DECREF(type);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
|
@ -1408,13 +1419,14 @@ select_epoll_close_impl(pyEpoll_Object *self)
|
|||
}
|
||||
|
||||
|
||||
static PyObject*
|
||||
pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
|
||||
static PyObject *
|
||||
pyepoll_get_closed(PyObject *op, void *Py_UNUSED(closure))
|
||||
{
|
||||
if (self->epfd < 0)
|
||||
pyEpoll_Object *self = pyEpoll_Object_CAST(op);
|
||||
if (self->epfd < 0) {
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
|
@ -1707,7 +1719,7 @@ select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
|
|||
}
|
||||
|
||||
static PyGetSetDef pyepoll_getsetlist[] = {
|
||||
{"closed", (getter)pyepoll_get_closed, NULL,
|
||||
{"closed", pyepoll_get_closed, NULL,
|
||||
"True if the epoll handler is closed"},
|
||||
{0},
|
||||
};
|
||||
|
@ -1777,13 +1789,16 @@ typedef struct {
|
|||
struct kevent e;
|
||||
} kqueue_event_Object;
|
||||
|
||||
#define kqueue_event_Check(op, state) (PyObject_TypeCheck((op), state->kqueue_event_Type))
|
||||
#define kqueue_event_Object_CAST(op) ((kqueue_event_Object *)(op))
|
||||
#define kqueue_event_Check(op, state) (PyObject_TypeCheck((op), state->kqueue_event_Type))
|
||||
|
||||
typedef struct kqueue_queue_Object {
|
||||
PyObject_HEAD
|
||||
SOCKET kqfd; /* kqueue control fd */
|
||||
} kqueue_queue_Object;
|
||||
|
||||
#define kqueue_queue_Object_CAST(op) ((kqueue_queue_Object *)(op))
|
||||
|
||||
#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
|
||||
# error uintptr_t does not match void *!
|
||||
#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
|
||||
|
@ -1876,9 +1891,9 @@ static struct PyMemberDef kqueue_event_members[] = {
|
|||
#undef KQ_OFF
|
||||
|
||||
static PyObject *
|
||||
|
||||
kqueue_event_repr(kqueue_event_Object *s)
|
||||
kqueue_event_repr(PyObject *op)
|
||||
{
|
||||
kqueue_event_Object *s = kqueue_event_Object_CAST(op);
|
||||
return PyUnicode_FromFormat(
|
||||
"<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
|
||||
"data=0x%llx udata=%p>",
|
||||
|
@ -1887,7 +1902,7 @@ kqueue_event_repr(kqueue_event_Object *s)
|
|||
}
|
||||
|
||||
static int
|
||||
kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
|
||||
kqueue_event_init(PyObject *op, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *pfd;
|
||||
static char *kwlist[] = {"ident", "filter", "flags", "fflags",
|
||||
|
@ -1896,11 +1911,14 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
|
|||
FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
|
||||
UINTPTRT_FMT_UNIT ":kevent";
|
||||
|
||||
kqueue_event_Object *self = kqueue_event_Object_CAST(op);
|
||||
EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
|
||||
&pfd, &(self->e.filter), &(self->e.flags),
|
||||
&(self->e.fflags), &(self->e.data), &(self->e.udata))) {
|
||||
&pfd, &(self->e.filter),
|
||||
&(self->e.flags), &(self->e.fflags),
|
||||
&(self->e.data), &(self->e.udata)))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1917,15 +1935,16 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
|
||||
int op)
|
||||
kqueue_event_richcompare(PyObject *lhs, PyObject *rhs, int op)
|
||||
{
|
||||
int result;
|
||||
kqueue_event_Object *s = kqueue_event_Object_CAST(lhs);
|
||||
_selectstate *state = _selectstate_by_type(Py_TYPE(s));
|
||||
|
||||
if (!kqueue_event_Check(o, state)) {
|
||||
if (!kqueue_event_Check(rhs, state)) {
|
||||
Py_RETURN_NOTIMPLEMENTED;
|
||||
}
|
||||
kqueue_event_Object *o = (kqueue_event_Object *)rhs; // fast cast
|
||||
|
||||
#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
|
||||
result = CMP(s->e.ident, o->e.ident)
|
||||
|
@ -1965,8 +1984,8 @@ kqueue_queue_err_closed(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
kqueue_tracking_after_fork(PyObject *module) {
|
||||
static PyObject *
|
||||
kqueue_tracking_after_fork(PyObject *module, PyObject *Py_UNUSED(dummy)) {
|
||||
_selectstate *state = get_select_state(module);
|
||||
_kqueue_list_item *item = state->kqueue_open_list;
|
||||
state->kqueue_open_list = NULL;
|
||||
|
@ -1984,7 +2003,7 @@ kqueue_tracking_after_fork(PyObject *module) {
|
|||
}
|
||||
|
||||
static PyMethodDef kqueue_tracking_after_fork_def = {
|
||||
"kqueue_tracking_after_fork", (PyCFunction)kqueue_tracking_after_fork,
|
||||
"kqueue_tracking_after_fork", kqueue_tracking_after_fork,
|
||||
METH_NOARGS, "Invalidate open select.kqueue objects after fork."
|
||||
};
|
||||
|
||||
|
@ -2173,10 +2192,11 @@ select_kqueue_impl(PyTypeObject *type)
|
|||
}
|
||||
|
||||
static void
|
||||
kqueue_queue_finalize(kqueue_queue_Object *self)
|
||||
kqueue_queue_finalize(PyObject *op)
|
||||
{
|
||||
PyObject* error = PyErr_GetRaisedException();
|
||||
kqueue_queue_internal_close(self);
|
||||
kqueue_queue_Object *self = kqueue_queue_Object_CAST(op);
|
||||
PyObject *error = PyErr_GetRaisedException();
|
||||
(void)kqueue_queue_internal_close(self);
|
||||
PyErr_SetRaisedException(error);
|
||||
}
|
||||
|
||||
|
@ -2201,13 +2221,14 @@ select_kqueue_close_impl(kqueue_queue_Object *self)
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
|
||||
static PyObject *
|
||||
kqueue_queue_get_closed(PyObject *op, void *Py_UNUSED(closure))
|
||||
{
|
||||
if (self->kqfd < 0)
|
||||
kqueue_queue_Object *self = kqueue_queue_Object_CAST(op);
|
||||
if (self->kqfd < 0) {
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
|
@ -2414,7 +2435,7 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
|
|||
}
|
||||
|
||||
static PyGetSetDef kqueue_queue_getsetlist[] = {
|
||||
{"closed", (getter)kqueue_queue_get_closed, NULL,
|
||||
{"closed", kqueue_queue_get_closed, NULL,
|
||||
"True if the kqueue handler is closed"},
|
||||
{0},
|
||||
};
|
||||
|
@ -2588,10 +2609,10 @@ _select_clear(PyObject *module)
|
|||
static void
|
||||
_select_free(void *module)
|
||||
{
|
||||
_select_clear((PyObject *)module);
|
||||
(void)_select_clear((PyObject *)module);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
_select_exec(PyObject *m)
|
||||
{
|
||||
_selectstate *state = get_select_state(m);
|
||||
|
|
Loading…
Reference in New Issue