]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
DBusConnection: implements _dbus_connection_set_pending_fds_function
authorAlban Crequy <alban.crequy@collabora.co.uk>
Fri, 18 Jul 2014 16:28:32 +0000 (17:28 +0100)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Mon, 15 Sep 2014 11:30:30 +0000 (12:30 +0100)
This is one of four commits needed to address CVE-2014-3637.

This will allow the bus to be notified whenever a file descriptor is added or
removed from a DBusConnection's DBusMessageLoader.

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=80559
Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
dbus/dbus-connection-internal.h
dbus/dbus-connection.c
dbus/dbus-message-internal.h
dbus/dbus-message-private.h
dbus/dbus-message.c
dbus/dbus-transport.c
dbus/dbus-transport.h

index 24e4772529fe7d1e3ac34285de35e7e845492f70..28974040d0467502f6c65cc08cf545f5aa7bbaa4 100644 (file)
@@ -44,6 +44,8 @@ typedef enum
 /** default timeout value when waiting for a message reply, 25 seconds */
 #define _DBUS_DEFAULT_TIMEOUT_VALUE (25 * 1000)
 
+typedef void (* DBusPendingFdsChangeFunction) (void *data);
+
 void              _dbus_connection_lock                        (DBusConnection     *connection);
 void              _dbus_connection_unlock                      (DBusConnection     *connection);
 DBusConnection *  _dbus_connection_ref_unlocked                (DBusConnection     *connection);
@@ -101,6 +103,9 @@ void              _dbus_connection_test_get_locks                 (DBusConnectio
                                                                    DBusCondVar **dispatch_cond_loc,
                                                                    DBusCondVar **io_path_cond_loc);
 int               _dbus_connection_get_pending_fds_count          (DBusConnection *connection);
+void              _dbus_connection_set_pending_fds_function       (DBusConnection *connection,
+                                                                   DBusPendingFdsChangeFunction callback,
+                                                                   void *data);
 
 /* if DBUS_ENABLE_STATS */
 void _dbus_connection_get_stats (DBusConnection *connection,
index 6aa24bc42cd2fee8c3c286a2f1914a109c00ca2a..b574207d3fe0cc8c20c4e4315697cd5e83c37800 100644 (file)
@@ -2560,6 +2560,22 @@ _dbus_connection_get_pending_fds_count (DBusConnection *connection)
   return _dbus_transport_get_pending_fds_count (connection->transport);
 }
 
+/**
+ * Register a function to be called whenever the number of pending file
+ * descriptors in the loader change.
+ *
+ * @param connection the connection
+ * @param callback the callback
+ */
+void
+_dbus_connection_set_pending_fds_function (DBusConnection *connection,
+                                           DBusPendingFdsChangeFunction callback,
+                                           void *data)
+{
+  _dbus_transport_set_pending_fds_function (connection->transport,
+                                            callback, data);
+}
+
 /** @} */
 
 /**
index 45cb026e1db68edff0e8dcd2b29a2ae701063202..e9a9ec01bff2eec7900b824833d265dba3bf9536 100644 (file)
@@ -97,6 +97,9 @@ void               _dbus_message_loader_set_max_message_unix_fds(DBusMessageLoad
                                                                  long                n);
 long               _dbus_message_loader_get_max_message_unix_fds(DBusMessageLoader  *loader);
 int                _dbus_message_loader_get_pending_fds_count (DBusMessageLoader  *loader);
+void               _dbus_message_loader_set_pending_fds_function (DBusMessageLoader *loader,
+                                                                  void (* callback) (void *),
+                                                                  void *data);
 
 typedef struct DBusInitialFDs DBusInitialFDs;
 DBusInitialFDs *_dbus_check_fdleaks_enter (void);
index e1578abd6c3f472fd6ebf0a6fc852c1cf6d94836..a611b09588ddc40468dde4bef7a9d8f478cc99ce 100644 (file)
@@ -80,6 +80,8 @@ struct DBusMessageLoader
   int *unix_fds; /**< File descriptors that have been read from the transport but not yet been handed to any message. Array will be allocated at first use. */
   unsigned n_unix_fds_allocated; /**< Number of file descriptors this array has space for */
   unsigned n_unix_fds; /**< Number of valid file descriptors in array */
+  void (* unix_fds_change) (void *); /**< Notify when the pending fds change */
+  void *unix_fds_change_data;
 #endif
 };
 
index 59f3bdc877353a76864382269e540fdfc4df41d9..3e74fc54e42c9091a917ebe957ad9af1e1e9341a 100644 (file)
@@ -4059,6 +4059,9 @@ _dbus_message_loader_return_unix_fds(DBusMessageLoader  *loader,
 
   loader->n_unix_fds += n_fds;
   loader->unix_fds_outstanding = FALSE;
+
+  if (n_fds && loader->unix_fds_change)
+    loader->unix_fds_change (loader->unix_fds_change_data);
 #else
   _dbus_assert_not_reached("Platform doesn't support unix fd passing");
 #endif
@@ -4206,6 +4209,9 @@ load_message (DBusMessageLoader *loader,
       message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
       loader->n_unix_fds -= n_unix_fds;
       memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0]));
+
+      if (loader->unix_fds_change)
+        loader->unix_fds_change (loader->unix_fds_change_data);
     }
   else
     message->unix_fds = NULL;
@@ -4514,6 +4520,25 @@ _dbus_message_loader_get_pending_fds_count (DBusMessageLoader *loader)
 #endif
 }
 
+/**
+ * Register a function to be called whenever the number of pending file
+ * descriptors in the loader change.
+ *
+ * @param loader the loader
+ * @param callback the callback
+ * @param data the data for the callback
+ */
+void
+_dbus_message_loader_set_pending_fds_function (DBusMessageLoader *loader,
+                                               void (* callback) (void *),
+                                               void *data)
+{
+#ifdef HAVE_UNIX_FD_PASSING
+  loader->unix_fds_change = callback;
+  loader->unix_fds_change_data = data;
+#endif
+}
+
 static DBusDataSlotAllocator slot_allocator =
   _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots));
 
index 690e5ba8b77f6e6edc2a59c7fe1d92d73145daac..f63e0ced402b1ba3bc5eaff65c37c765c29e9b4d 100644 (file)
@@ -1523,6 +1523,22 @@ _dbus_transport_get_pending_fds_count (DBusTransport *transport)
   return _dbus_message_loader_get_pending_fds_count (transport->loader);
 }
 
+/**
+ * Register a function to be called whenever the number of pending file
+ * descriptors in the loader change.
+ *
+ * @param transport the transport
+ * @param callback the callback
+ */
+void
+_dbus_transport_set_pending_fds_function (DBusTransport *transport,
+                                           void (* callback) (void *),
+                                           void *data)
+{
+  _dbus_message_loader_set_pending_fds_function (transport->loader,
+                                                 callback, data);
+}
+
 #ifdef DBUS_ENABLE_STATS
 void
 _dbus_transport_get_stats (DBusTransport  *transport,
index ff102f3a8244ce9d03faa1bafc9f41e02a38e156..39c74c46666d2ce91307c02ea2cd11a08f8ca23e 100644 (file)
@@ -98,6 +98,9 @@ dbus_bool_t        _dbus_transport_set_auth_mechanisms    (DBusTransport
 void               _dbus_transport_set_allow_anonymous    (DBusTransport              *transport,
                                                            dbus_bool_t                 value);
 int                _dbus_transport_get_pending_fds_count  (DBusTransport              *transport);
+void               _dbus_transport_set_pending_fds_function (DBusTransport *transport,
+                                                             void (* callback) (void *),
+                                                             void *data);
 
 /* if DBUS_ENABLE_STATS */
 void _dbus_transport_get_stats (DBusTransport  *transport,