Commit Graph

135 Commits

Author SHA1 Message Date
Lucas De Marchi
ef27c6c7fa gdbus: Remove connection from pending_property functions
The reply to a DBus.Properties.Set() method call should go through the
same D-Bus connection. Thus remove the DBusConnection parameter from the
following functions:

    - g_dbus_pending_property_success()
    - g_dbus_pending_property_error_valist()
    - g_dbus_pending_property_error()
2012-10-19 10:33:20 +03:00
Johan Hedberg
85f7f41819 gdbus: Fix invalid memory access during interface removal
If an interface is removed from the root path during the same mainloop
iteration that it was added we need to check for data->added before
doing the check for data->parent == NULL in the remove_interface()
function. Otherwise the added interface doesn't get removed from the
data->added list and will result in accessing freed memory:

==337== Invalid read of size 8
==337==    at 0x4F65AFA: dbus_message_iter_append_basic (in /usr/lib64/libdbus-1.so.3.7.1)
==337==    by 0x1247B5: append_interface (object.c:556)
==337==    by 0x4C8DC5C: g_slist_foreach (gslist.c:840)
==337==    by 0x1261F7: process_changes (object.c:594)
==337==    by 0x126372: generic_unregister (object.c:997)
==337==    by 0x4F69669: ??? (in /usr/lib64/libdbus-1.so.3.7.1)
==337==    by 0x4F5CE51: dbus_connection_unregister_object_path (in /usr/lib64/libdbus-1.so.3.7.1)
==337==    by 0x125E81: object_path_unref (object.c:1236)
==337==    by 0x126136: g_dbus_unregister_interface (object.c:1361)
==337==    by 0x14CDF0: service_exit (service.c:581)
==337==    by 0x177556: plugin_cleanup (plugin.c:242)
==337==    by 0x12221F: main (main.c:559)
==337==  Address 0x5bc1550 is 0 bytes inside a block of size 56 free'd
==337==    at 0x4A079AE: free (vg_replace_malloc.c:427)
==337==    by 0x4C7850E: g_free (gmem.c:252)
==337==    by 0x125DB0: remove_interface (object.c:671)
==337==    by 0x125E3B: object_path_unref (object.c:1230)
==337==    by 0x126136: g_dbus_unregister_interface (object.c:1361)
==337==    by 0x14CDF0: service_exit (service.c:581)
==337==    by 0x177556: plugin_cleanup (plugin.c:242)
==337==    by 0x12221F: main (main.c:559)
2012-10-15 13:21:11 +03:00
Johan Hedberg
1d862e73f4 gdbus: Add g_dbus_get_properties function
This function can be used to construct custom D-Bus messages containing
the properties for a specific interface on a given path.
2012-10-12 18:03:09 +03:00
Johan Hedberg
297691b0a6 gdbus: Add support for invalidated properties
If there's a pending property but its exists() callback returns false
the property should be considered invalidated and included in the
relevant list of the PropertiesChanged signal.
2012-10-11 16:45:34 +02:00
Johan Hedberg
7828b1d6fa gdbus: Fix processing pending properties in remove_interface() 2012-10-08 15:00:25 +02:00
Lucas De Marchi
335bd95d00 gdbus: Fix up Properties.Set() code path
Minor fixes to make setter actually work:

	- Add propdata in pending_property_set
	- Break loop when we are removing propdata from list and we
	  found it
	- in_args and out_args were swapped
	- interface and method name arguments were swapped
2012-10-06 09:44:24 +02:00
Lucas De Marchi
1997090d42 gdbus: Fix invalid memory access while unregistering
If an interface is added and removed on the same mailoop iteration,
ObjectManager would try to send InterfacesAdded signal while running the
idler because the interface was added to data->added list.

This is easily reproduced by forcing an error path in a plugin
registration, like on sap_server_register(), resulting in the following
error:

==11795== Invalid read of size 4
==11795==    at 0x496F592: dbus_message_iter_append_basic (dbus-message.c:2598)
==11795==    by 0x117B39: append_interface (object.c:554)
==11795==    by 0x48955E7: g_slist_foreach (gslist.c:840)
==11795==    by 0x11923B: process_changes (object.c:592)
==11795==    by 0x11956D: generic_unregister (object.c:980)
==11795==    by 0x4973BAC: _dbus_object_tree_unregister_and_unlock (dbus-object-tree.c:516)
==11795==    by 0x4965240: dbus_connection_unregister_object_path (dbus-connection.c:5776)
==11795==    by 0x1178A5: object_path_unref (object.c:1219)
==11795==    by 0x118517: g_dbus_unregister_interface (object.c:1344)
==11795==    by 0x19AF5B: sap_exit (sap.c:385)
==11795==    by 0x13E9E2: sap_server_register (server.c:1428)
==11795==    by 0x13C092: sap_server_probe (manager.c:44)

With this patch we don't send the InterfacesAdded signal, removing it
from data->added while unregistering.
2012-10-05 21:55:24 +02:00
Lucas De Marchi
9f63f87ad0 gdbus: Implement PropertiesChanged signal 2012-10-04 17:10:36 +03:00
Luiz Augusto von Dentz
343c29cfff gdbus: Simplify code for appending properties
This reuse append_properties for GetAll and GetManagedObjects
2012-10-04 17:10:27 +03:00
Luiz Augusto von Dentz
dc46dc50f2 gdbus: Integrates ObjectManager with Properties interface
This appends the properties and its values when using ObjectManager.
2012-10-04 17:10:19 +03:00
Luiz Augusto von Dentz
e20532b7a9 gdbus: Only export ObjectManager interface on root path
ObjectManager should be exported only in the root path and list all
the children paths.
2012-10-04 17:10:11 +03:00
Luiz Augusto von Dentz
3cfba3f7c1 gdbus: Group interface changes to reduce the amount of signals emitted
InterfacesAdded and InterfacesRemoved can group all the interfaces
changes together in one message.
2012-10-04 17:10:01 +03:00
Luiz Augusto von Dentz
b487ef05d2 gdbus: Add support for org.freedesktop.DBus.ObjectManager interface
This implements initial support for ObjectManager, it automatically adds
objects to its parents so no action is needed by daemons to get their
objects managed by this interface.

ObjectManager is part of D-Bus spec since revision 0.17:
http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager
2012-10-04 17:09:51 +03:00
Lucas De Marchi
21de7d71fb gdbus: Add properties into Introspectable interface 2012-10-04 17:09:26 +03:00
Lucas De Marchi
913a901526 gdbus: Implement DBus.Properties.Set method
Contrary to Get() and GetAll(), Set() is asynchronous so we pass an id
to the setter so later it can declare the Set() as successful or
otherwise.
2012-10-04 17:07:33 +03:00
Lucas De Marchi
2b75d65ad1 gdbus: Implement DBus.Properties.GetAll method 2012-10-04 17:05:45 +03:00
Lucas De Marchi
c374734a86 gdbus: Implement DBus.Properties.Get method 2012-10-04 17:05:25 +03:00
Lucas De Marchi
a5b71bdd78 gdbus: Add skeleton of DBus.Properties interface
This interface is responsible for handling properties of all objects in
a given path. Right now it only registers itself, doing nothing useful.
A conversion to this new layout will be done by subsequent patches.

org.freedesktop.org.DBus.Properties spec can be found at
http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties
2012-10-04 17:05:24 +03:00
Lucas De Marchi
312d738e0e gdbus: Use macros to add annotations
Besides being more readable this way it avoids going over 80 chars.
2012-10-04 17:05:22 +03:00
Lucas De Marchi
7084f0baf5 gdbus: Move typedefs up
Move the typedefs up so they can be used by functions and callbacks.
2012-10-04 17:05:20 +03:00
Luiz Augusto von Dentz
e4bf2b16dd gdbus: Fix not freeing list node by using g_slist_delete_link
g_slist_remove_link does not free the node which can cause leaks so
replace that with g_slist_delete_link which does free memory properly.
2012-10-03 14:38:42 +03:00
Lucas De Marchi
57a2ff308f gdbus: Refactor filter_data_find()
Now this function is only used for searching the listeners of a
connection and the other parameters are not needed anymore.
2012-09-27 10:53:44 +03:00
Lucas De Marchi
5a6aa22549 gdbus: Fix wrong signal handler match
When we add a signal handler with g_dbus_add_signal_watch(), this
function tries to multiplex the matches added in libdbus by checking
if there's a previous filter_data with the same fields. However, if the
field is NULL it accepts as being the same. The result is that the
following watches will use the same filter data:

watch1 = g_dbus_add_signal_watch(conn, BUS_NAME, NULL, iface, member,
						cb1, data1, NULL);
watch2 = g_dbus_add_signal_watch(conn, BUS_NAME, "/path2", iface, member,
						cb2, data2, NULL);
watch3 = g_dbus_add_signal_watch(conn, BUS_NAME, "/path3", iface, member,
						cb3, data3, NULL);

The result is that when a signal arrives with path == "/path2", all 3
callbacks above will be called, with the same signal delivered to all of
them.

Another problem is that, if we invert the calls like below, only signals
to cb1 will never be trigerred, nonetheless it used path == NULL.

watch2 = g_dbus_add_signal_watch(conn, BUS_NAME, "/path2", iface, member,
						cb2, data2, NULL);
watch1 = g_dbus_add_signal_watch(conn, BUS_NAME, NULL, iface, member,
						cb1, data1, NULL);
watch3 = g_dbus_add_signal_watch(conn, BUS_NAME, "/path3", iface, member,
						cb3, data3, NULL);

This is fixed by not multiplexing the matchs with filter data if any of
the fields are different, including being NULL. When a signal arrives,
if a field is NULL we accept it as a match, but not when adding the
signal handler.
2012-09-27 10:53:44 +03:00
Johan Hedberg
abfc2b0dd5 gdbus: Fix crash when getting disconnected from the bus
When getting disconnected from the bus sometimes (maybe always?)
dbus_watch_handle() can cause the "info" context to be free'd meaning
that we should not try to access it after the call. The only member we
need access to is the connection pointer and as the code already has a
ref() call for it it's only natural to solve the issue by adding a local
variable not dependent on "info".

The backtrace of the crash fixed looks as follows:

 Invalid read of size 8
   at 0x121085: watch_func (mainloop.c:105)
   by 0x4C72694: g_main_context_dispatch (gmain.c:2539)
   by 0x4C729C7: g_main_context_iterate.isra.23 (gmain.c:3146)
   by 0x4C72DC1: g_main_loop_run (gmain.c:3340)
   by 0x120541: main (main.c:551)
 Address 0x5bbcd90 is 16 bytes inside a block of size 24 free'd
   at 0x4A079AE: free (vg_replace_malloc.c:427)
   by 0x4C7837E: g_free (gmem.c:252)
   by 0x4F708BF: dbus_watch_set_data (dbus-watch.c:614)
   by 0x4F70938: _dbus_watch_unref (dbus-watch.c:132)
   by 0x4F6E9A7: _dbus_transport_handle_watch (dbus-transport.c:884)
   by 0x4F59AFB: _dbus_connection_handle_watch (dbus-connection.c:1497)
   by 0x4F70AF9: dbus_watch_handle (dbus-watch.c:683)
   by 0x121084: watch_func (mainloop.c:103)
   by 0x4C72694: g_main_context_dispatch (gmain.c:2539)
   by 0x4C729C7: g_main_context_iterate.isra.23 (gmain.c:3146)
   by 0x4C72DC1: g_main_loop_run (gmain.c:3340)
   by 0x120541: main (main.c:551)
2012-09-26 21:45:05 +03:00
Jaganath Kanakkassery
ee3b0b2b33 gdbus: Fix compilation error if macro "error" is defined
The variable "signature" used in error is not defined and "args" is now
a struct instead of a string.
2012-08-16 22:00:22 +03:00
Lucas De Marchi
ca0b4c4c65 gdbus: Fix removal of filter after last filter_data
If there's a signal watch that's also watching for name
(data->name_watch) currently we are trying to remove the message_filter
twice since we may have the following call chain:

filter_data_remove_callback()
  filter_data_free()
    g_dbus_remove_watch()
      filter_data_remove_callback()
	filter_data_free()
        dbus_connection_remove_filter()
  dbus_connection_remove_filter()

Because of this we can't currently watch for signals passing the bus
name. After this patch we don't have this issue anymore.

We fix it by removing the filter before calling filter_data_free() if we
are the last filter_data and thus avoid calling
dbus_connection_remove_filter() twice.
2012-06-28 10:37:42 +03:00
Lucas De Marchi
80525c138b gdbus: add macro for methods marked as NOREPLY 2012-06-18 17:32:18 +03:00
Mikel Astiz
5c6bd559e9 gdbus: Fix incorrectly discarded signals
Signals with no arguments were incorrectly filtered out due to the NULL
inequality check.
2012-05-22 20:26:41 +02:00
Lucas De Marchi
67da9a4630 gdbus: do not check signature twice
Message signature is already checked in generic_message(), so there's no
need to check again in the callback.
2012-05-17 20:32:21 -07:00
Lucas De Marchi
e6ebddb1f1 gdbus: add Method.NoReply annotation in introspection 2012-05-17 20:32:21 -07:00
Lucas De Marchi
53e3faaf2b gdbus: add Deprecated annotation in introspection 2012-05-17 20:32:21 -07:00
Lucas De Marchi
e77a7c2775 gdbus: remove signature and reply from tables 2012-05-17 20:32:21 -07:00
Lucas De Marchi
fd9148dd25 gdbus: loop over args to check message signature 2012-05-17 20:32:20 -07:00
Lucas De Marchi
c430735fd4 gdbus: use GDBusArgInfo to generate introspection
By using GDBusArgInfo in methods and signals, the introspection
generation is much simpler and we can add each argument name.
2012-05-17 20:32:20 -07:00
Lucas De Marchi
2e576dd2f9 gdbus: add and use helpers for table declarations 2012-05-17 20:32:20 -07:00
Lucas De Marchi
56f4b3c8ae gdbus: add argument info to methods and signals 2012-05-17 20:32:20 -07:00
Marcel Holtmann
b01bcc4215 gdbus: Constify introspection method table 2012-05-17 19:56:27 -07:00
Lucas De Marchi
a40aa24e83 gdbus: do not call memset for terminating NUL 2012-05-17 19:53:53 -07:00
Lucas De Marchi
417d485119 gdbus: return if method signature is malformed 2012-05-17 19:52:59 -07:00
Marcel Holtmann
2c8caaf0ba gdbus: Remove unneeded NEED_DBUS_WATCH_GET_UNIX_FD check 2012-04-16 18:23:01 +02:00
Anderson Lizardo
c4494591c9 gdbus: Use destroy callback for service watch
Even though service watches accepted a "destroy" callback, they were
being ignored. This fix properly pass them along so they are called when
the watch is removed.
2012-04-04 12:56:51 +03:00
Syam Sidhardhan
e1d2db4976 gdbus: Fix white space coding style issue
- corrected the space before '{'
2011-07-09 19:10:04 +03:00
Szymon Janc
3c07ee5578 Remove unused result variable from g_dbus_pending_success 2011-05-15 01:47:11 +03:00
Grant Erickson
af4519a50c gdbus: Unconditionally remove D-Bus timeouts
Address an issue in which the daemon incorrectly handles D-Bus main
loop timeouts by only removing timeouts that are not enabled when
D-Bus requests a timeout removal.
2011-03-09 13:34:03 -08:00
Daniel Wagner
f1d07327bf gdbus: Remove root node 'name' attribute in introspection
generate_introspection_xml generates the root <node> tags with a
'name' attribute. This seems to be a valid attribute but it is not
consistent with the way the D-Bus daemon generates empty nodes.

For example if we register "/foo/bar", D-Bus daemon will generate for
"/foo" a introspection which looks like this:

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
  <node name="bar"/>
</node>

and generate_introspection_xml generates for "/foo/bar":

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/foo/bar">
</node>

Just don't add the 'name' attribute to the root node.  The GLib
binding for D-Bus does it the same way.
2011-01-19 20:36:47 +05:30
Daniel Wagner
eea57f916c gdbus: invaldate_parent_data: walk the whole path down
Assume there is only one object registerd at "/". If we add a new
object at "/foo/bar" the introspection of "/" has to be updated. A new
node has to be added at "/".

invalidate_parent_data stops invaldating the whole path because the
boolean return value of dbus_connection_get_object_path_data is used
wrong.

If we get a TRUE just go on down in the path, if FALSE is return
dbus_connection_get_object_path_data has run out of memory.
2011-01-19 20:36:45 +05:30
Marcel Holtmann
e7c4557de7 gdbus: Update copyright information 2011-01-01 17:32:11 -08:00
Johan Hedberg
986ff02852 gdbus: fix accessing freed callback data
cb->disc_func or cb->conn_func could remove the callback so this needs
to be checked for before continuing processing.
2010-12-09 22:02:30 +02:00
Lucas De Marchi
6e66423fe8 gdbus: explicitly compare pointers to NULL
This patch was generated by the following semantic patch
(http://coccinelle.lip6.fr/)

// <smpl>
@fix disable is_null,isnt_null1@
expression *E;
@@

- !E
+ E == NULL
// </smpl>
2010-12-08 16:33:28 +01:00
Luiz Augusto von Dentz
fd6b74727b gdbus: fix not handling bus disconnects
We where not dispatching data when a bus disconnects which cause
Disconnected signal to not be processed and thus causing the process to
either not exit or to not trigger callbacks registered with
g_dbus_set_disconnect_function.

To fix this now we always schedule a dispatch which will make sure data
still not processed will make its way to the proper handlers even if
disconnected.
2010-10-13 15:53:44 +03:00