From 1791bf0ff1fb364c3c338e163bf228736e40027f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 12:45:00 +0100 Subject: [PATCH 01/11] fix UBSan failures for `pollObject` --- Modules/selectmodule.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index e14e114a6dafd0..64ebf1ab20f476 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -440,6 +440,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. */ @@ -773,11 +775,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); From 74a36055341cd0f268b534a9f37d6e89243bfaee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 12:47:00 +0100 Subject: [PATCH 02/11] fix UBSan failures for `devpollObject` --- Modules/selectmodule.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 64ebf1ab20f476..95f7bc79e336f5 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -799,6 +799,8 @@ typedef struct { struct pollfd *fds; } devpollObject; +#define devpollObject_CAST(op) ((devpollObject *)(op)) + static PyObject * devpoll_err_closed(void) { @@ -1091,13 +1093,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] @@ -1117,7 +1120,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}, }; @@ -1168,9 +1171,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); From ff0d90442d8ec6f10a8016efa6a1b148218f96d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 12:50:11 +0100 Subject: [PATCH 03/11] fix UBSan failures for `pyEpoll_Object` --- Modules/selectmodule.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 95f7bc79e336f5..ac62104ee65300 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -1284,6 +1284,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) { @@ -1386,13 +1388,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] @@ -1417,13 +1420,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] @@ -1716,7 +1720,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}, }; From 08462e86f23309813e28f6c8f41dcf2fa1ce13e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 12:59:48 +0100 Subject: [PATCH 04/11] fix UBSan failures for `kqueue_event_Object` --- Modules/selectmodule.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index ac62104ee65300..9e101e04aa1092 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -1790,7 +1790,8 @@ 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 @@ -1889,9 +1890,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( "", @@ -1900,7 +1901,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", @@ -1909,11 +1910,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; } @@ -1930,8 +1934,7 @@ 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; _selectstate *state = _selectstate_by_type(Py_TYPE(s)); @@ -1940,6 +1943,9 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, Py_RETURN_NOTIMPLEMENTED; } + kqueue_event_Object *s = kqueue_event_Object_CAST(lhs); + 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) : CMP(s->e.filter, o->e.filter) From bfbed25d0444461226e2a8cfb89ff5bc855163aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:00:14 +0100 Subject: [PATCH 05/11] fix UBSan failures for `kqueue_tracking_after_fork` --- Modules/selectmodule.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 9e101e04aa1092..9306648ebc4edf 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -1984,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(args)) { _selectstate *state = get_select_state(module); _kqueue_list_item *item = state->kqueue_open_list; state->kqueue_open_list = NULL; @@ -2003,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." }; From bfb9b81b90ce4e97f32b5ceafbd017121b59fc42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:04:01 +0100 Subject: [PATCH 06/11] fix UBSan failures for `kqueue_queue_Object` --- Modules/selectmodule.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 9306648ebc4edf..1081041dee2fe2 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -1798,6 +1798,8 @@ typedef struct kqueue_queue_Object { 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) @@ -2192,10 +2194,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); } @@ -2220,13 +2223,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] @@ -2433,7 +2437,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}, }; From abd37543fd31626eddaecc256ffa46c5b3d88a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:04:06 +0100 Subject: [PATCH 07/11] suppress unused return values --- Modules/selectmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 1081041dee2fe2..e2c85fc82b3db6 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -2611,7 +2611,7 @@ _select_clear(PyObject *module) static void _select_free(void *module) { - _select_clear((PyObject *)module); + (void)_select_clear((PyObject *)module); } int From 6f30e5597e2e52bfbd25ca4ded4b7adfd05a37c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Fri, 7 Feb 2025 13:08:25 +0100 Subject: [PATCH 08/11] fix compilation --- Modules/selectmodule.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 85a366b5ca104c..53297ff2e30899 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -1938,13 +1938,12 @@ static PyObject * 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)) { Py_RETURN_NOTIMPLEMENTED; } - - kqueue_event_Object *s = kqueue_event_Object_CAST(lhs); kqueue_event_Object *o = (kqueue_event_Object *)rhs; // fast cast #define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1) From 8a1c309c7882394d0c9391c73fae32129429c973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Fri, 7 Feb 2025 13:09:07 +0100 Subject: [PATCH 09/11] fix compilation --- Modules/selectmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 53297ff2e30899..16e576f896cf10 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -1941,7 +1941,7 @@ kqueue_event_richcompare(PyObject *lhs, PyObject *rhs, int op) 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 From 7a0ca33775f4c14da1f18ee2956448f39eab3f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 22 Feb 2025 10:50:51 +0100 Subject: [PATCH 10/11] fix semantic naming --- Modules/selectmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 16e576f896cf10..9fb6c4dcc42b3b 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -1985,7 +1985,7 @@ kqueue_queue_err_closed(void) } static PyObject * -kqueue_tracking_after_fork(PyObject *module, PyObject *Py_UNUSED(args)) { +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; From 91dfee463f50f0e2de904a4ef5877f867700accc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 23 Feb 2025 11:06:42 +0100 Subject: [PATCH 11/11] declare `_select_exec` function as being static --- Modules/selectmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 9fb6c4dcc42b3b..d701026b50887c 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -2612,7 +2612,7 @@ _select_free(void *module) (void)_select_clear((PyObject *)module); } -int +static int _select_exec(PyObject *m) { _selectstate *state = get_select_state(m);