From fccf4cb7f430d8278796e273dde44c275bfac042 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, 25 Jan 2025 16:51:11 +0100 Subject: [PATCH 1/3] fix UBSan failures for `OverlappedObject` --- Modules/_winapi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 260cab48091c16..28e9765431f5ba 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -144,14 +144,17 @@ typedef struct { Py_buffer write_buffer; } OverlappedObject; +#define _OverlappedObject_CAST(op) ((OverlappedObject *)(op)) + /* Note: tp_clear (overlapped_clear) is not implemented because it requires cancelling the IO operation if it's pending and the cancellation is quite complex and can fail (see: overlapped_dealloc). */ static int -overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) +overlapped_traverse(PyObject *op, visitproc visit, void *arg) { + OverlappedObject *self = _OverlappedObject_CAST(op); Py_VISIT(self->read_buffer); Py_VISIT(self->write_buffer.obj); Py_VISIT(Py_TYPE(self)); @@ -159,10 +162,11 @@ overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) } static void -overlapped_dealloc(OverlappedObject *self) +overlapped_dealloc(PyObject *op) { DWORD bytes; int err = GetLastError(); + OverlappedObject *self = _OverlappedObject_CAST(op); PyObject_GC_UnTrack(self); if (self->pending) { From c38e3d39b06bd81910dc0e446a892128e556fe44 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, 25 Jan 2025 16:51:18 +0100 Subject: [PATCH 2/3] suppress unused return values --- Modules/_winapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 28e9765431f5ba..ef8fbcd7d51b8d 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -3220,7 +3220,7 @@ winapi_clear(PyObject *module) static void winapi_free(void *module) { - winapi_clear((PyObject *)module); + (void)winapi_clear((PyObject *)module); } static struct PyModuleDef winapi_module = { From 72737d076ac4358ba60063a95c7599fff620040c 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, 8 Feb 2025 10:21:13 +0100 Subject: [PATCH 3/3] Do Do not use `_` + capital letter in new code as it is also UB. --- Modules/_winapi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 78a947568c32ac..4391bfc09f9cb8 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -144,7 +144,7 @@ typedef struct { Py_buffer write_buffer; } OverlappedObject; -#define _OverlappedObject_CAST(op) ((OverlappedObject *)(op)) +#define OverlappedObject_CAST(op) ((OverlappedObject *)(op)) /* Note: tp_clear (overlapped_clear) is not implemented because it @@ -154,7 +154,7 @@ quite complex and can fail (see: overlapped_dealloc). static int overlapped_traverse(PyObject *op, visitproc visit, void *arg) { - OverlappedObject *self = _OverlappedObject_CAST(op); + OverlappedObject *self = OverlappedObject_CAST(op); Py_VISIT(self->read_buffer); Py_VISIT(self->write_buffer.obj); Py_VISIT(Py_TYPE(self)); @@ -166,7 +166,7 @@ overlapped_dealloc(PyObject *op) { DWORD bytes; int err = GetLastError(); - OverlappedObject *self = _OverlappedObject_CAST(op); + OverlappedObject *self = OverlappedObject_CAST(op); PyObject_GC_UnTrack(self); if (self->pending) {