#18 libdbus-1.so segmentation fault with generated connman 1.12 adapter

all
open
nobody
None
1
2013-12-15
2013-09-14
p-rimes
No

I am unable to run a stable, minimal runloop with a generated net.connman.Manager adapter via the latest gitorious sources as of this posting.
Runloop is using the provided BusDispatcher; my minimal test main() is as follows (with generated adapter header, and application source including derived proxy class/main() as file attachments):
int main (int argc, char** argv)
{
DBus::BusDispatcher dispatcher;
DBus::_init_threading();
DBus::default_dispatcher = &dispatcher;
DBus::Connection conn = DBus::Connection::SystemBus();

ConnmanClient client(conn, "/", "net.connman");

dispatcher.enter();
return 0;
}
With the connmand server running and monitoring your network interfaces, disabling/re-enabling the primary network interface:
ifconfig eth0 down
ifconfig eth0 up
the runloop segfaults while processing the GetServices callback (which is emitted every time the network interfaces change, and which is successfully handled for non-primary network interfaces, or transitions to 'down' on the primary; only transitions to 'up' on the primary cause a reliable segfault).

FYI the GetServices DBus method signature is 'a(oa{sv})'.

3 Attachments

Discussion

  • I found the same problem. After some investigation I found this to be the offending call (src/message.c:349):

      dbus_message_iter_open_container
      (
        (DBusMessageIter *) & (to._iter),
        from.type(),
        from.type() == DBUS_TYPE_VARIANT ? NULL : sig,
        (DBusMessageIter *) & (to_container._iter)
      );
    

    The function 'dbus_message_iter_open_container' is from libdbus. Its documentation says the following in regards to the third parameter, contained_signature:

    Container types are for example struct, variant, and array. For variants, the contained_signature should be the type of the single value inside the variant. For structs and dict entries, contained_signature should be NULL; it will be set to whatever types you write into the struct. For arrays, contained_signature should be the type of the array elements.

    Simply put, variants should pass their contained type, structs and dict_entries should pass NULL, and arrays should pass the type of their elements.

    I modified the call to look like this:

      dbus_message_iter_open_container
      (
        (DBusMessageIter *) & (to._iter),
        from.type(),
        ( ( from.type() == DBUS_TYPE_STRUCT ) ||
          ( from.type() == DBUS_TYPE_DICT_ENTRY ) ) ? NULL : sig,
        (DBusMessageIter *) & (to_container._iter)
      );
    

    So structs and dict_entry types will pass NULL, otherwise the contained signature is passed.

    Attached is a patch.

    Ryan

     
    Last edit: Ryan Bryngelson 2013-12-15
    Attachments