Skip to content

Commit 2a5f976

Browse files
committed
Fix SIGSEGV if DbusExportHandle outlives exported object
Avoid exposing `SdBusInterface.slot` because the slot object depends on `SdBusInterface->vtable`. Instead provide a method to stop exporting.
1 parent 2e0ffa6 commit 2a5f976

File tree

3 files changed

+17
-8
lines changed

3 files changed

+17
-8
lines changed

src/sdbus/dbus_proxy_async_interface_base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -453,11 +453,8 @@ def new_proxy(
453453
class DbusExportHandle:
454454
def __init__(self, local_meta: DbusLocalObjectMeta):
455455
self._tasks = local_meta.tasks
456-
self._dbus_slots: list[SdBusSlot] = [
457-
i.slot
458-
for i in local_meta.activated_interfaces
459-
if i.slot is not None
460-
]
456+
self._dbus_slots: list[SdBusSlot] = []
457+
self._dbus_interfaces = local_meta.activated_interfaces
461458

462459
async def __aenter__(self) -> DbusExportHandle:
463460
return self
@@ -485,5 +482,8 @@ def stop(self) -> None:
485482
for task in self._tasks:
486483
task.cancel("D-Bus export stopped")
487484

485+
for interface in self._dbus_interfaces:
486+
interface._stop_export()
487+
488488
for slot in self._dbus_slots:
489489
slot.close()

src/sdbus/sd_bus_internals.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ def close(self) -> None:
4949

5050

5151
class SdBusInterface:
52-
slot: Optional[SdBusSlot]
5352
method_list: list[object]
5453
method_dict: dict[bytes, object]
5554
property_list: list[object]
@@ -86,6 +85,9 @@ def add_signal(
8685
) -> None:
8786
raise NotImplementedError(__STUB_ERROR)
8887

88+
def _stop_export(self) -> None:
89+
raise NotImplementedError(__STUB_ERROR)
90+
8991

9092
class SdBusMessage:
9193
def append_data(self, signature: str, *args: DbusCompleteTypes) -> None:

src/sdbus/sd_bus_internals_interface.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,16 +323,23 @@ static PyObject* SdBusInterface_create_vtable(SdBusInterfaceObject* self, PyObje
323323
Py_RETURN_NONE;
324324
}
325325

326+
static PyObject* SdBus_stop_export(SdBusInterfaceObject* self, PyObject* Py_UNUSED(args)) {
327+
Py_XDECREF(self->interface_slot);
328+
self->interface_slot = NULL;
329+
330+
Py_RETURN_NONE;
331+
}
332+
326333
static PyMethodDef SdBusInterface_methods[] = {
327334
{"add_method", (SD_BUS_PY_FUNC_TYPE)SdBusInterface_add_method, SD_BUS_PY_METH, PyDoc_STR("Add method to the D-Bus interface.")},
328335
{"add_property", (SD_BUS_PY_FUNC_TYPE)SdBusInterface_add_property, SD_BUS_PY_METH, PyDoc_STR("Add property to the D-Bus interface.")},
329336
{"add_signal", (SD_BUS_PY_FUNC_TYPE)SdBusInterface_add_signal, SD_BUS_PY_METH, PyDoc_STR("Add signal to the D-Bus interface.")},
330337
{"_create_vtable", (PyCFunction)SdBusInterface_create_vtable, METH_NOARGS, PyDoc_STR("Creates the vtable.")},
338+
{"_stop_export", (PyCFunction)SdBus_stop_export, METH_NOARGS, PyDoc_STR("Stop exporting object.")},
331339
{NULL, NULL, 0, NULL},
332340
};
333341

334-
static PyMemberDef SdBusInterface_members[] = {{"slot", T_OBJECT, offsetof(SdBusInterfaceObject, interface_slot), READONLY, NULL},
335-
{"method_list", T_OBJECT, offsetof(SdBusInterfaceObject, method_list), READONLY, NULL},
342+
static PyMemberDef SdBusInterface_members[] = {{"method_list", T_OBJECT, offsetof(SdBusInterfaceObject, method_list), READONLY, NULL},
336343
{"method_dict", T_OBJECT, offsetof(SdBusInterfaceObject, method_dict), READONLY, NULL},
337344
{"property_list", T_OBJECT, offsetof(SdBusInterfaceObject, property_list), READONLY, NULL},
338345
{"property_get_dict", T_OBJECT, offsetof(SdBusInterfaceObject, property_get_dict), READONLY, NULL},

0 commit comments

Comments
 (0)