Skip to content

Commit 6669905

Browse files
authored
pythongh-111178: fix UBSan failures in Modules/_interp*module.c (pythonGH-129779)
Fix UBSan failures for `XIBufferViewObject` Remove redundant casts, suppress unused return values
1 parent 7ea8927 commit 6669905

File tree

3 files changed

+52
-44
lines changed

3 files changed

+52
-44
lines changed

Modules/_interpchannelsmodule.c

+33-29
Original file line numberDiff line numberDiff line change
@@ -2268,6 +2268,8 @@ typedef struct channelid {
22682268
_channels *channels;
22692269
} channelid;
22702270

2271+
#define channelid_CAST(op) ((channelid *)(op))
2272+
22712273
struct channel_id_converter_data {
22722274
PyObject *module;
22732275
int64_t cid;
@@ -2396,10 +2398,11 @@ _channelid_new(PyObject *mod, PyTypeObject *cls,
23962398
}
23972399

23982400
static void
2399-
channelid_dealloc(PyObject *self)
2401+
channelid_dealloc(PyObject *op)
24002402
{
2401-
int64_t cid = ((channelid *)self)->cid;
2402-
_channels *channels = ((channelid *)self)->channels;
2403+
channelid *self = channelid_CAST(op);
2404+
int64_t cid = self->cid;
2405+
_channels *channels = self->channels;
24032406

24042407
PyTypeObject *tp = Py_TYPE(self);
24052408
tp->tp_free(self);
@@ -2420,7 +2423,7 @@ channelid_repr(PyObject *self)
24202423
PyTypeObject *type = Py_TYPE(self);
24212424
const char *name = _PyType_Name(type);
24222425

2423-
channelid *cidobj = (channelid *)self;
2426+
channelid *cidobj = channelid_CAST(self);
24242427
const char *fmt;
24252428
if (cidobj->end == CHANNEL_SEND) {
24262429
fmt = "%s(%" PRId64 ", send=True)";
@@ -2437,21 +2440,21 @@ channelid_repr(PyObject *self)
24372440
static PyObject *
24382441
channelid_str(PyObject *self)
24392442
{
2440-
channelid *cidobj = (channelid *)self;
2443+
channelid *cidobj = channelid_CAST(self);
24412444
return PyUnicode_FromFormat("%" PRId64 "", cidobj->cid);
24422445
}
24432446

24442447
static PyObject *
24452448
channelid_int(PyObject *self)
24462449
{
2447-
channelid *cidobj = (channelid *)self;
2450+
channelid *cidobj = channelid_CAST(self);
24482451
return PyLong_FromLongLong(cidobj->cid);
24492452
}
24502453

24512454
static Py_hash_t
24522455
channelid_hash(PyObject *self)
24532456
{
2454-
channelid *cidobj = (channelid *)self;
2457+
channelid *cidobj = channelid_CAST(self);
24552458
PyObject *pyid = PyLong_FromLongLong(cidobj->cid);
24562459
if (pyid == NULL) {
24572460
return -1;
@@ -2483,10 +2486,10 @@ channelid_richcompare(PyObject *self, PyObject *other, int op)
24832486
goto done;
24842487
}
24852488

2486-
channelid *cidobj = (channelid *)self;
2489+
channelid *cidobj = channelid_CAST(self);
24872490
int equal;
24882491
if (PyObject_TypeCheck(other, state->ChannelIDType)) {
2489-
channelid *othercidobj = (channelid *)other;
2492+
channelid *othercidobj = (channelid *)other; // fast safe cast
24902493
equal = (cidobj->end == othercidobj->end) && (cidobj->cid == othercidobj->cid);
24912494
}
24922495
else if (PyLong_Check(other)) {
@@ -2606,17 +2609,18 @@ _channelid_shared(PyThreadState *tstate, PyObject *obj, _PyXIData_t *data)
26062609
return -1;
26072610
}
26082611
struct _channelid_xid *xid = (struct _channelid_xid *)_PyXIData_DATA(data);
2609-
xid->cid = ((channelid *)obj)->cid;
2610-
xid->end = ((channelid *)obj)->end;
2611-
xid->resolve = ((channelid *)obj)->resolve;
2612+
channelid *cidobj = channelid_CAST(obj);
2613+
xid->cid = cidobj->cid;
2614+
xid->end = cidobj->end;
2615+
xid->resolve = cidobj->resolve;
26122616
return 0;
26132617
}
26142618

26152619
static PyObject *
26162620
channelid_end(PyObject *self, void *end)
26172621
{
26182622
int force = 1;
2619-
channelid *cidobj = (channelid *)self;
2623+
channelid *cidobj = channelid_CAST(self);
26202624
if (end != NULL) {
26212625
PyObject *obj = NULL;
26222626
int err = newchannelid(Py_TYPE(self), cidobj->cid, *(int *)end,
@@ -2649,11 +2653,11 @@ static int _channelid_end_send = CHANNEL_SEND;
26492653
static int _channelid_end_recv = CHANNEL_RECV;
26502654

26512655
static PyGetSetDef channelid_getsets[] = {
2652-
{"end", (getter)channelid_end, NULL,
2656+
{"end", channelid_end, NULL,
26532657
PyDoc_STR("'send', 'recv', or 'both'")},
2654-
{"send", (getter)channelid_end, NULL,
2658+
{"send", channelid_end, NULL,
26552659
PyDoc_STR("the 'send' end of the channel"), &_channelid_end_send},
2656-
{"recv", (getter)channelid_end, NULL,
2660+
{"recv", channelid_end, NULL,
26572661
PyDoc_STR("the 'recv' end of the channel"), &_channelid_end_recv},
26582662
{NULL}
26592663
};
@@ -2662,16 +2666,16 @@ PyDoc_STRVAR(channelid_doc,
26622666
"A channel ID identifies a channel and may be used as an int.");
26632667

26642668
static PyType_Slot channelid_typeslots[] = {
2665-
{Py_tp_dealloc, (destructor)channelid_dealloc},
2669+
{Py_tp_dealloc, channelid_dealloc},
26662670
{Py_tp_doc, (void *)channelid_doc},
2667-
{Py_tp_repr, (reprfunc)channelid_repr},
2668-
{Py_tp_str, (reprfunc)channelid_str},
2671+
{Py_tp_repr, channelid_repr},
2672+
{Py_tp_str, channelid_str},
26692673
{Py_tp_hash, channelid_hash},
26702674
{Py_tp_richcompare, channelid_richcompare},
26712675
{Py_tp_getset, channelid_getsets},
26722676
// number slots
2673-
{Py_nb_int, (unaryfunc)channelid_int},
2674-
{Py_nb_index, (unaryfunc)channelid_int},
2677+
{Py_nb_int, channelid_int},
2678+
{Py_nb_index, channelid_int},
26752679
{0, NULL},
26762680
};
26772681

@@ -2904,10 +2908,10 @@ channelsmod_create(PyObject *self, PyObject *args, PyObject *kwds)
29042908
if (state == NULL) {
29052909
return NULL;
29062910
}
2907-
PyObject *cidobj = NULL;
2911+
channelid *cidobj = NULL;
29082912
int err = newchannelid(state->ChannelIDType, cid, 0,
29092913
&_globals.channels, 0, 0,
2910-
(channelid **)&cidobj);
2914+
&cidobj);
29112915
if (handle_channel_error(err, self, cid)) {
29122916
assert(cidobj == NULL);
29132917
err = channel_destroy(&_globals.channels, cid);
@@ -2917,8 +2921,8 @@ channelsmod_create(PyObject *self, PyObject *args, PyObject *kwds)
29172921
return NULL;
29182922
}
29192923
assert(cidobj != NULL);
2920-
assert(((channelid *)cidobj)->channels != NULL);
2921-
return cidobj;
2924+
assert(cidobj->channels != NULL);
2925+
return (PyObject *)cidobj;
29222926
}
29232927

29242928
PyDoc_STRVAR(channelsmod_create_doc,
@@ -3553,7 +3557,7 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
35533557
{
35543558
module_state *state = get_module_state(mod);
35553559
assert(state != NULL);
3556-
traverse_module_state(state, visit, arg);
3560+
(void)traverse_module_state(state, visit, arg);
35573561
return 0;
35583562
}
35593563

@@ -3564,18 +3568,18 @@ module_clear(PyObject *mod)
35643568
assert(state != NULL);
35653569

35663570
// Now we clear the module state.
3567-
clear_module_state(state);
3571+
(void)clear_module_state(state);
35683572
return 0;
35693573
}
35703574

35713575
static void
35723576
module_free(void *mod)
35733577
{
3574-
module_state *state = get_module_state(mod);
3578+
module_state *state = get_module_state((PyObject *)mod);
35753579
assert(state != NULL);
35763580

35773581
// Now we clear the module state.
3578-
clear_module_state(state);
3582+
(void)clear_module_state(state);
35793583

35803584
_globals_fini();
35813585
}

Modules/_interpqueuesmodule.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -1934,7 +1934,7 @@ static int
19341934
module_traverse(PyObject *mod, visitproc visit, void *arg)
19351935
{
19361936
module_state *state = get_module_state(mod);
1937-
traverse_module_state(state, visit, arg);
1937+
(void)traverse_module_state(state, visit, arg);
19381938
return 0;
19391939
}
19401940

@@ -1944,17 +1944,17 @@ module_clear(PyObject *mod)
19441944
module_state *state = get_module_state(mod);
19451945

19461946
// Now we clear the module state.
1947-
clear_module_state(state);
1947+
(void)clear_module_state(state);
19481948
return 0;
19491949
}
19501950

19511951
static void
19521952
module_free(void *mod)
19531953
{
1954-
module_state *state = get_module_state(mod);
1954+
module_state *state = get_module_state((PyObject *)mod);
19551955

19561956
// Now we clear the module state.
1957-
clear_module_state(state);
1957+
(void)clear_module_state(state);
19581958

19591959
_globals_fini();
19601960
}
@@ -1968,7 +1968,7 @@ static struct PyModuleDef moduledef = {
19681968
.m_slots = module_slots,
19691969
.m_traverse = module_traverse,
19701970
.m_clear = module_clear,
1971-
.m_free = (freefunc)module_free,
1971+
.m_free = module_free,
19721972
};
19731973

19741974
PyMODINIT_FUNC

Modules/_interpretersmodule.c

+14-10
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ typedef struct {
8383
int64_t interpid;
8484
} XIBufferViewObject;
8585

86+
#define XIBufferViewObject_CAST(op) ((XIBufferViewObject *)(op))
87+
8688
static PyObject *
8789
xibufferview_from_xid(PyTypeObject *cls, _PyXIData_t *data)
8890
{
@@ -100,8 +102,9 @@ xibufferview_from_xid(PyTypeObject *cls, _PyXIData_t *data)
100102
}
101103

102104
static void
103-
xibufferview_dealloc(XIBufferViewObject *self)
105+
xibufferview_dealloc(PyObject *op)
104106
{
107+
XIBufferViewObject *self = XIBufferViewObject_CAST(op);
105108
PyInterpreterState *interp = _PyInterpreterState_LookUpID(self->interpid);
106109
/* If the interpreter is no longer alive then we have problems,
107110
since other objects may be using the buffer still. */
@@ -124,20 +127,21 @@ xibufferview_dealloc(XIBufferViewObject *self)
124127
}
125128

126129
static int
127-
xibufferview_getbuf(XIBufferViewObject *self, Py_buffer *view, int flags)
130+
xibufferview_getbuf(PyObject *op, Py_buffer *view, int flags)
128131
{
129132
/* Only PyMemoryView_FromObject() should ever call this,
130133
via _memoryview_from_xid() below. */
134+
XIBufferViewObject *self = XIBufferViewObject_CAST(op);
131135
*view = *self->view;
132-
view->obj = (PyObject *)self;
136+
view->obj = op;
133137
// XXX Should we leave it alone?
134138
view->internal = NULL;
135139
return 0;
136140
}
137141

138142
static PyType_Slot XIBufferViewType_slots[] = {
139-
{Py_tp_dealloc, (destructor)xibufferview_dealloc},
140-
{Py_bf_getbuffer, (getbufferproc)xibufferview_getbuf},
143+
{Py_tp_dealloc, xibufferview_dealloc},
144+
{Py_bf_getbuffer, xibufferview_getbuf},
141145
// We don't bother with Py_bf_releasebuffer since we don't need it.
142146
{0, NULL},
143147
};
@@ -1548,7 +1552,7 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
15481552
{
15491553
module_state *state = get_module_state(mod);
15501554
assert(state != NULL);
1551-
traverse_module_state(state, visit, arg);
1555+
(void)traverse_module_state(state, visit, arg);
15521556
return 0;
15531557
}
15541558

@@ -1557,16 +1561,16 @@ module_clear(PyObject *mod)
15571561
{
15581562
module_state *state = get_module_state(mod);
15591563
assert(state != NULL);
1560-
clear_module_state(state);
1564+
(void)clear_module_state(state);
15611565
return 0;
15621566
}
15631567

15641568
static void
15651569
module_free(void *mod)
15661570
{
1567-
module_state *state = get_module_state(mod);
1571+
module_state *state = get_module_state((PyObject *)mod);
15681572
assert(state != NULL);
1569-
clear_module_state(state);
1573+
(void)clear_module_state(state);
15701574
}
15711575

15721576
static struct PyModuleDef moduledef = {
@@ -1578,7 +1582,7 @@ static struct PyModuleDef moduledef = {
15781582
.m_slots = module_slots,
15791583
.m_traverse = module_traverse,
15801584
.m_clear = module_clear,
1581-
.m_free = (freefunc)module_free,
1585+
.m_free = module_free,
15821586
};
15831587

15841588
PyMODINIT_FUNC

0 commit comments

Comments
 (0)