https://github.com/python/cpython/commit/6669905723238d45cde6c8a9b40579bfe73c76c1
commit: 6669905723238d45cde6c8a9b40579bfe73c76c1
branch: main
author: Bénédikt Tran <10796600+picn...@users.noreply.github.com>
committer: encukou <encu...@gmail.com>
date: 2025-02-17T11:34:14+01:00
summary:

gh-111178: fix UBSan failures in `Modules/_interp*module.c` (GH-129779)

Fix UBSan failures for `XIBufferViewObject`

Remove redundant casts, suppress unused return values

files:
M Modules/_interpchannelsmodule.c
M Modules/_interpqueuesmodule.c
M Modules/_interpretersmodule.c

diff --git a/Modules/_interpchannelsmodule.c b/Modules/_interpchannelsmodule.c
index 75d69ade1d3c9b..fc54277cdc0ba0 100644
--- a/Modules/_interpchannelsmodule.c
+++ b/Modules/_interpchannelsmodule.c
@@ -2268,6 +2268,8 @@ typedef struct channelid {
     _channels *channels;
 } channelid;
 
+#define channelid_CAST(op)  ((channelid *)(op))
+
 struct channel_id_converter_data {
     PyObject *module;
     int64_t cid;
@@ -2396,10 +2398,11 @@ _channelid_new(PyObject *mod, PyTypeObject *cls,
 }
 
 static void
-channelid_dealloc(PyObject *self)
+channelid_dealloc(PyObject *op)
 {
-    int64_t cid = ((channelid *)self)->cid;
-    _channels *channels = ((channelid *)self)->channels;
+    channelid *self = channelid_CAST(op);
+    int64_t cid = self->cid;
+    _channels *channels = self->channels;
 
     PyTypeObject *tp = Py_TYPE(self);
     tp->tp_free(self);
@@ -2420,7 +2423,7 @@ channelid_repr(PyObject *self)
     PyTypeObject *type = Py_TYPE(self);
     const char *name = _PyType_Name(type);
 
-    channelid *cidobj = (channelid *)self;
+    channelid *cidobj = channelid_CAST(self);
     const char *fmt;
     if (cidobj->end == CHANNEL_SEND) {
         fmt = "%s(%" PRId64 ", send=True)";
@@ -2437,21 +2440,21 @@ channelid_repr(PyObject *self)
 static PyObject *
 channelid_str(PyObject *self)
 {
-    channelid *cidobj = (channelid *)self;
+    channelid *cidobj = channelid_CAST(self);
     return PyUnicode_FromFormat("%" PRId64 "", cidobj->cid);
 }
 
 static PyObject *
 channelid_int(PyObject *self)
 {
-    channelid *cidobj = (channelid *)self;
+    channelid *cidobj = channelid_CAST(self);
     return PyLong_FromLongLong(cidobj->cid);
 }
 
 static Py_hash_t
 channelid_hash(PyObject *self)
 {
-    channelid *cidobj = (channelid *)self;
+    channelid *cidobj = channelid_CAST(self);
     PyObject *pyid = PyLong_FromLongLong(cidobj->cid);
     if (pyid == NULL) {
         return -1;
@@ -2483,10 +2486,10 @@ channelid_richcompare(PyObject *self, PyObject *other, 
int op)
         goto done;
     }
 
-    channelid *cidobj = (channelid *)self;
+    channelid *cidobj = channelid_CAST(self);
     int equal;
     if (PyObject_TypeCheck(other, state->ChannelIDType)) {
-        channelid *othercidobj = (channelid *)other;
+        channelid *othercidobj = (channelid *)other;  // fast safe cast
         equal = (cidobj->end == othercidobj->end) && (cidobj->cid == 
othercidobj->cid);
     }
     else if (PyLong_Check(other)) {
@@ -2606,9 +2609,10 @@ _channelid_shared(PyThreadState *tstate, PyObject *obj, 
_PyXIData_t *data)
         return -1;
     }
     struct _channelid_xid *xid = (struct _channelid_xid *)_PyXIData_DATA(data);
-    xid->cid = ((channelid *)obj)->cid;
-    xid->end = ((channelid *)obj)->end;
-    xid->resolve = ((channelid *)obj)->resolve;
+    channelid *cidobj = channelid_CAST(obj);
+    xid->cid = cidobj->cid;
+    xid->end = cidobj->end;
+    xid->resolve = cidobj->resolve;
     return 0;
 }
 
@@ -2616,7 +2620,7 @@ static PyObject *
 channelid_end(PyObject *self, void *end)
 {
     int force = 1;
-    channelid *cidobj = (channelid *)self;
+    channelid *cidobj = channelid_CAST(self);
     if (end != NULL) {
         PyObject *obj = NULL;
         int err = newchannelid(Py_TYPE(self), cidobj->cid, *(int *)end,
@@ -2649,11 +2653,11 @@ static int _channelid_end_send = CHANNEL_SEND;
 static int _channelid_end_recv = CHANNEL_RECV;
 
 static PyGetSetDef channelid_getsets[] = {
-    {"end", (getter)channelid_end, NULL,
+    {"end", channelid_end, NULL,
      PyDoc_STR("'send', 'recv', or 'both'")},
-    {"send", (getter)channelid_end, NULL,
+    {"send", channelid_end, NULL,
      PyDoc_STR("the 'send' end of the channel"), &_channelid_end_send},
-    {"recv", (getter)channelid_end, NULL,
+    {"recv", channelid_end, NULL,
      PyDoc_STR("the 'recv' end of the channel"), &_channelid_end_recv},
     {NULL}
 };
@@ -2662,16 +2666,16 @@ PyDoc_STRVAR(channelid_doc,
 "A channel ID identifies a channel and may be used as an int.");
 
 static PyType_Slot channelid_typeslots[] = {
-    {Py_tp_dealloc, (destructor)channelid_dealloc},
+    {Py_tp_dealloc, channelid_dealloc},
     {Py_tp_doc, (void *)channelid_doc},
-    {Py_tp_repr, (reprfunc)channelid_repr},
-    {Py_tp_str, (reprfunc)channelid_str},
+    {Py_tp_repr, channelid_repr},
+    {Py_tp_str, channelid_str},
     {Py_tp_hash, channelid_hash},
     {Py_tp_richcompare, channelid_richcompare},
     {Py_tp_getset, channelid_getsets},
     // number slots
-    {Py_nb_int, (unaryfunc)channelid_int},
-    {Py_nb_index,  (unaryfunc)channelid_int},
+    {Py_nb_int, channelid_int},
+    {Py_nb_index, channelid_int},
     {0, NULL},
 };
 
@@ -2904,10 +2908,10 @@ channelsmod_create(PyObject *self, PyObject *args, 
PyObject *kwds)
     if (state == NULL) {
         return NULL;
     }
-    PyObject *cidobj = NULL;
+    channelid *cidobj = NULL;
     int err = newchannelid(state->ChannelIDType, cid, 0,
                            &_globals.channels, 0, 0,
-                           (channelid **)&cidobj);
+                           &cidobj);
     if (handle_channel_error(err, self, cid)) {
         assert(cidobj == NULL);
         err = channel_destroy(&_globals.channels, cid);
@@ -2917,8 +2921,8 @@ channelsmod_create(PyObject *self, PyObject *args, 
PyObject *kwds)
         return NULL;
     }
     assert(cidobj != NULL);
-    assert(((channelid *)cidobj)->channels != NULL);
-    return cidobj;
+    assert(cidobj->channels != NULL);
+    return (PyObject *)cidobj;
 }
 
 PyDoc_STRVAR(channelsmod_create_doc,
@@ -3553,7 +3557,7 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
 {
     module_state *state = get_module_state(mod);
     assert(state != NULL);
-    traverse_module_state(state, visit, arg);
+    (void)traverse_module_state(state, visit, arg);
     return 0;
 }
 
@@ -3564,18 +3568,18 @@ module_clear(PyObject *mod)
     assert(state != NULL);
 
     // Now we clear the module state.
-    clear_module_state(state);
+    (void)clear_module_state(state);
     return 0;
 }
 
 static void
 module_free(void *mod)
 {
-    module_state *state = get_module_state(mod);
+    module_state *state = get_module_state((PyObject *)mod);
     assert(state != NULL);
 
     // Now we clear the module state.
-    clear_module_state(state);
+    (void)clear_module_state(state);
 
     _globals_fini();
 }
diff --git a/Modules/_interpqueuesmodule.c b/Modules/_interpqueuesmodule.c
index 808938a9e8cd16..d069880e2750de 100644
--- a/Modules/_interpqueuesmodule.c
+++ b/Modules/_interpqueuesmodule.c
@@ -1934,7 +1934,7 @@ static int
 module_traverse(PyObject *mod, visitproc visit, void *arg)
 {
     module_state *state = get_module_state(mod);
-    traverse_module_state(state, visit, arg);
+    (void)traverse_module_state(state, visit, arg);
     return 0;
 }
 
@@ -1944,17 +1944,17 @@ module_clear(PyObject *mod)
     module_state *state = get_module_state(mod);
 
     // Now we clear the module state.
-    clear_module_state(state);
+    (void)clear_module_state(state);
     return 0;
 }
 
 static void
 module_free(void *mod)
 {
-    module_state *state = get_module_state(mod);
+    module_state *state = get_module_state((PyObject *)mod);
 
     // Now we clear the module state.
-    clear_module_state(state);
+    (void)clear_module_state(state);
 
     _globals_fini();
 }
@@ -1968,7 +1968,7 @@ static struct PyModuleDef moduledef = {
     .m_slots = module_slots,
     .m_traverse = module_traverse,
     .m_clear = module_clear,
-    .m_free = (freefunc)module_free,
+    .m_free = module_free,
 };
 
 PyMODINIT_FUNC
diff --git a/Modules/_interpretersmodule.c b/Modules/_interpretersmodule.c
index fcd0baf696f943..d4d90b5f31b7ab 100644
--- a/Modules/_interpretersmodule.c
+++ b/Modules/_interpretersmodule.c
@@ -83,6 +83,8 @@ typedef struct {
     int64_t interpid;
 } XIBufferViewObject;
 
+#define XIBufferViewObject_CAST(op) ((XIBufferViewObject *)(op))
+
 static PyObject *
 xibufferview_from_xid(PyTypeObject *cls, _PyXIData_t *data)
 {
@@ -100,8 +102,9 @@ xibufferview_from_xid(PyTypeObject *cls, _PyXIData_t *data)
 }
 
 static void
-xibufferview_dealloc(XIBufferViewObject *self)
+xibufferview_dealloc(PyObject *op)
 {
+    XIBufferViewObject *self = XIBufferViewObject_CAST(op);
     PyInterpreterState *interp = _PyInterpreterState_LookUpID(self->interpid);
     /* If the interpreter is no longer alive then we have problems,
        since other objects may be using the buffer still. */
@@ -124,20 +127,21 @@ xibufferview_dealloc(XIBufferViewObject *self)
 }
 
 static int
-xibufferview_getbuf(XIBufferViewObject *self, Py_buffer *view, int flags)
+xibufferview_getbuf(PyObject *op, Py_buffer *view, int flags)
 {
     /* Only PyMemoryView_FromObject() should ever call this,
        via _memoryview_from_xid() below. */
+    XIBufferViewObject *self = XIBufferViewObject_CAST(op);
     *view = *self->view;
-    view->obj = (PyObject *)self;
+    view->obj = op;
     // XXX Should we leave it alone?
     view->internal = NULL;
     return 0;
 }
 
 static PyType_Slot XIBufferViewType_slots[] = {
-    {Py_tp_dealloc, (destructor)xibufferview_dealloc},
-    {Py_bf_getbuffer, (getbufferproc)xibufferview_getbuf},
+    {Py_tp_dealloc, xibufferview_dealloc},
+    {Py_bf_getbuffer, xibufferview_getbuf},
     // We don't bother with Py_bf_releasebuffer since we don't need it.
     {0, NULL},
 };
@@ -1548,7 +1552,7 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
 {
     module_state *state = get_module_state(mod);
     assert(state != NULL);
-    traverse_module_state(state, visit, arg);
+    (void)traverse_module_state(state, visit, arg);
     return 0;
 }
 
@@ -1557,16 +1561,16 @@ module_clear(PyObject *mod)
 {
     module_state *state = get_module_state(mod);
     assert(state != NULL);
-    clear_module_state(state);
+    (void)clear_module_state(state);
     return 0;
 }
 
 static void
 module_free(void *mod)
 {
-    module_state *state = get_module_state(mod);
+    module_state *state = get_module_state((PyObject *)mod);
     assert(state != NULL);
-    clear_module_state(state);
+    (void)clear_module_state(state);
 }
 
 static struct PyModuleDef moduledef = {
@@ -1578,7 +1582,7 @@ static struct PyModuleDef moduledef = {
     .m_slots = module_slots,
     .m_traverse = module_traverse,
     .m_clear = module_clear,
-    .m_free = (freefunc)module_free,
+    .m_free = module_free,
 };
 
 PyMODINIT_FUNC

_______________________________________________
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