GDBus_codegen or documentation has an error that results in double-free bugs
I've been implementing a DBus server using GDBus_codegen, and found that either the code generated by GDBus_codegen, or the examples in the documentation, are wrong.
The problem is that in the C examples, when calling XXXX_complete_YYYY(skeleton, invocation);
inside the signal callback, they pass the pointer to invocation
as-is, and it is freed inside the call. But then, when the signal callback returns, the invocation
object is freed again.
The generated code for XXXX_complete_YYYY(skeleton, invocation)
just passes the invocation as-is into g_dbus_method_invocation_return_value(invocation, result)
, so, for the examples to work as expected as they are written, the generated code should add a g_object_ref()
for the invocation
pointer and change the signature from "transfer: full" to "transfer: none"; or the examples should be fixed by changind the complete
calls to XXXX_complete_YYYY(skeleton, g_object_ref(invocation));
.
I attach a .zip file with an example of this (buildable with meson/ninja): it creates a well-known DBus object in the user bus, called org.test.memorybug
, with an object called org/test/memorybug
with an interface org.test.memorybug
. That interface has two methods: TestNoRef()
and TestWithRef()
.
Launching the program with valgrind ./memory-bug-test
and calling, using d-feet, to TestWithRef()
, there will be no errors or memory problems; but calling TestNoRef()
, instead, will trigger an access to a previously-freed memory block, the one that belonged to invocation
, because it was already freed by g_dbus_method_invocation_return_value()
.