Sophie

Sophie

distrib > Mageia > 3 > x86_64 > by-pkgid > 9bd6c61b93a77b33aa5c068cb9529372 > files > 11

dbus-1.6.8-4.5.mga3.src.rpm

From 01e32d6ddcfdcbd63cf1c8053f6e5d2ffdfbaa91 Mon Sep 17 00:00:00 2001
From: Alban Crequy <alban.crequy@collabora.co.uk>
Date: Fri, 18 Jul 2014 17:28:32 +0100
Subject: [PATCH 07/10] DBusConnection: implements
 _dbus_connection_set_pending_fds_function

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>
(cherry picked from commit 8021fd84267ee1394d96f4a119adb57de3971a62)
Conflicts:
	dbus/dbus-message.c
---
 dbus/dbus-connection-internal.h |  5 +++++
 dbus/dbus-connection.c          | 16 ++++++++++++++++
 dbus/dbus-message-internal.h    |  3 +++
 dbus/dbus-message-private.h     |  2 ++
 dbus/dbus-message.c             | 25 +++++++++++++++++++++++++
 dbus/dbus-transport.c           | 16 ++++++++++++++++
 dbus/dbus-transport.h           |  3 +++
 7 files changed, 70 insertions(+)

diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h
index f5edf3c..badeabf 100644
--- a/dbus/dbus-connection-internal.h
+++ b/dbus/dbus-connection-internal.h
@@ -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,
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index 07a9ebf..e1068e3 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -2543,6 +2543,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);
+}
+
 /** @} */
 
 /**
diff --git a/dbus/dbus-message-internal.h b/dbus/dbus-message-internal.h
index de03edd..76540f4 100644
--- a/dbus/dbus-message-internal.h
+++ b/dbus/dbus-message-internal.h
@@ -98,6 +98,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);
diff --git a/dbus/dbus-message-private.h b/dbus/dbus-message-private.h
index e1578ab..a611b09 100644
--- a/dbus/dbus-message-private.h
+++ b/dbus/dbus-message-private.h
@@ -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
 };
 
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
index 5d70f69..43cb1be 100644
--- a/dbus/dbus-message.c
+++ b/dbus/dbus-message.c
@@ -3984,6 +3984,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
@@ -4131,6 +4134,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;
@@ -4443,6 +4449,25 @@ _dbus_message_loader_get_pending_fds_count (DBusMessageLoader *loader)
 }
 
 /**
+ * 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
+}
+
+/**
  * Allocates an integer ID to be used for storing application-specific
  * data on any DBusMessage. The allocated ID may then be used
  * with dbus_message_set_data() and dbus_message_get_data().
diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c
index e4d03c1..9846cc6 100644
--- a/dbus/dbus-transport.c
+++ b/dbus/dbus-transport.c
@@ -1502,6 +1502,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,
diff --git a/dbus/dbus-transport.h b/dbus/dbus-transport.h
index 6a3a8b3..0d5a6e5 100644
--- a/dbus/dbus-transport.h
+++ b/dbus/dbus-transport.h
@@ -97,6 +97,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,
-- 
2.1.0