https://github.com/python/cpython/commit/deac31d214f8d562c9683471d42296ea16a3c641
commit: deac31d214f8d562c9683471d42296ea16a3c641
branch: main
author: Bénédikt Tran <[email protected]>
committer: encukou <[email protected]>
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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]