https://github.com/python/cpython/commit/deac31d214f8d562c9683471d42296ea16a3c641
commit: deac31d214f8d562c9683471d42296ea16a3c641
branch: main
author: Bénédikt Tran <10796600+picn...@users.noreply.github.com>
committer: encukou <encu...@gmail.com>
date: 2025-02-20T14:24:24+01:00
summary:

gh-111178: fix UBSan failures in `Modules/overlapped.c` (GH-129786)

Fix UBSan failures for `OverlappedObject`

files:
M Modules/overlapped.c

diff --git a/Modules/overlapped.c b/Modules/overlapped.c
index 806ebee7a70ff1..0eba109f4902fc 100644
--- a/Modules/overlapped.c
+++ b/Modules/overlapped.c
@@ -124,6 +124,8 @@ typedef struct {
     };
 } OverlappedObject;
 
+#define OverlappedObject_CAST(op)   ((OverlappedObject *)(op))
+
 
 static inline void
 steal_buffer(Py_buffer * dst, Py_buffer * src)
@@ -666,8 +668,14 @@ _overlapped_Overlapped_impl(PyTypeObject *type, HANDLE 
event)
 
 
 /* Note (bpo-32710): OverlappedType.tp_clear is not defined to not release
-   buffers while overlapped are still running, to prevent a crash. */
-static int
+ * buffers while overlapped are still running, to prevent a crash.
+ *
+ * Note (gh-111178): Since OverlappedType.tp_clear is not used, we do not
+ * need to prevent an undefined behaviour by changing the type of 'self'.
+ * To avoid suppressing unused return values, we however make this function
+ * return nothing instead of 0, as we never use it.
+ */
+static void
 Overlapped_clear(OverlappedObject *self)
 {
     switch (self->type) {
@@ -709,16 +717,16 @@ Overlapped_clear(OverlappedObject *self)
         }
     }
     self->type = TYPE_NOT_STARTED;
-    return 0;
 }
 
 static void
-Overlapped_dealloc(OverlappedObject *self)
+Overlapped_dealloc(PyObject *op)
 {
     DWORD bytes;
     DWORD olderr = GetLastError();
     BOOL wait = FALSE;
     BOOL ret;
+    OverlappedObject *self = OverlappedObject_CAST(op);
 
     if (!HasOverlappedIoCompleted(&self->overlapped) &&
         self->type != TYPE_NOT_STARTED)
@@ -1642,21 +1650,24 @@ 
_overlapped_Overlapped_ConnectPipe_impl(OverlappedObject *self,
 }
 
 static PyObject*
-Overlapped_getaddress(OverlappedObject *self)
+Overlapped_getaddress(PyObject *op, void *Py_UNUSED(closure))
 {
+    OverlappedObject *self = OverlappedObject_CAST(op);
     return PyLong_FromVoidPtr(&self->overlapped);
 }
 
 static PyObject*
-Overlapped_getpending(OverlappedObject *self)
+Overlapped_getpending(PyObject *op, void *Py_UNUSED(closure))
 {
+    OverlappedObject *self = OverlappedObject_CAST(op);
     return PyBool_FromLong(!HasOverlappedIoCompleted(&self->overlapped) &&
                            self->type != TYPE_NOT_STARTED);
 }
 
 static int
-Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg)
+Overlapped_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    OverlappedObject *self = OverlappedObject_CAST(op);
     switch (self->type) {
     case TYPE_READ:
     case TYPE_ACCEPT:
@@ -1976,9 +1987,9 @@ static PyMemberDef Overlapped_members[] = {
 };
 
 static PyGetSetDef Overlapped_getsets[] = {
-    {"address", (getter)Overlapped_getaddress, NULL,
+    {"address", Overlapped_getaddress, NULL,
      "Address of overlapped structure"},
-    {"pending", (getter)Overlapped_getpending, NULL,
+    {"pending", Overlapped_getpending, NULL,
      "Whether the operation is pending"},
     {NULL},
 };

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to