[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#785301: jessie-pu: package dbus/1.8.18-0+deb8u1



Package: release.debian.org
Severity: normal
Tags: jessie
User: release.debian.org@packages.debian.org
Usertags: pu

Hi,
I'd like to upload the just-released dbus/1.8.18 to jessie
after it has had some testing in sid (i.e. reached testing).
It contains some security hardening and threading bugfixes
which seem valuable to have, and I'd also like to track the 1.8
branch to simplify future security updates.

I am the upstream maintainer, and I can revert anything you consider
unacceptable for jessie (either via a Debian patch or upstream).

I attach a filtered debdiff, omitting Autotools goo, Windows-specific
files, and the CMake build system that is not used in Debian.

Thanks,
    S
debdiff dbus_1.8.16-1.dsc dbus_1.8.18-0+deb8u1.dsc | filterdiff -p1 -x Makefile.in -x '*/Makefile.in' -x '*/*/Makefile.in' -x 'cmake/*' -x configure -x dbus/dbus-sysdeps-win.c >| dbus_1.8.18-0+deb8u1-filtered.diff

diffstat for dbus-1.8.16 dbus-1.8.18

 Makefile.in                   |    5 ++--
 NEWS                          |   47 +++++++++++++++++++++++++++++++++++++
 bus/Makefile.in               |    1 
 bus/session.conf.in           |   10 ++++++++
 cmake/CMakeLists.txt          |    4 +++
 cmake/test/CMakeLists.txt     |    5 ++++
 configure                     |   36 ++++++++++++++++++-----------
 configure.ac                  |   11 +++++++-
 dbus/Makefile.in              |    1 
 dbus/dbus-internals.c         |    4 +--
 dbus/dbus-marshal-recursive.c |   29 ++++++++++++-----------
 dbus/dbus-message.c           |    5 +++-
 dbus/dbus-nonce.c             |    8 +++++-
 dbus/dbus-resources.c         |   52 +++++++++++++++++++++++++++++++++++++-----
 dbus/dbus-server.c            |    5 +++-
 dbus/dbus-sysdeps-win.c       |   16 +++++++++++-
 dbus/dbus-transport.c         |    4 +--
 debian/changelog              |   11 ++++++++
 doc/Makefile.in               |    1 
 test/Makefile.am              |    5 ++++
 test/Makefile.in              |   37 +++++++++++++++++++++++++----
 test/manual-tcp.c             |   46 +++++++++++++++++++++++++++++++++++++
 test/name-test/Makefile.in    |    1 
 test/relay.c                  |    4 +++
 tools/Makefile.in             |    1 
 25 files changed, 300 insertions(+), 49 deletions(-)

diff -Nru dbus-1.8.16/bus/session.conf.in dbus-1.8.18/bus/session.conf.in
--- dbus-1.8.16/bus/session.conf.in	2015-02-03 15:47:02.000000000 +0000
+++ dbus-1.8.18/bus/session.conf.in	2015-05-14 13:23:29.000000000 +0100
@@ -14,6 +14,16 @@
 
   <listen>@DBUS_SESSION_BUS_LISTEN_ADDRESS@</listen>
 
+  <!-- On Unix systems, the most secure authentication mechanism is
+  EXTERNAL, which uses credential-passing over Unix sockets.
+
+  This authentication mechanism is not available on Windows,
+  is not suitable for use with the tcp: or nonce-tcp: transports,
+  and will not work on obscure flavours of Unix that do not have
+  a supported credentials-passing mechanism. On those platforms/transports,
+  comment out the <auth> element to allow fallback to DBUS_COOKIE_SHA1. -->
+  @DBUS_SESSION_CONF_MAYBE_AUTH_EXTERNAL@
+
   <standard_session_servicedirs />
 
   <policy context="default">
diff -Nru dbus-1.8.16/configure.ac dbus-1.8.18/configure.ac
--- dbus-1.8.16/configure.ac	2015-02-04 16:45:19.000000000 +0000
+++ dbus-1.8.18/configure.ac	2015-05-14 13:28:34.000000000 +0100
@@ -3,7 +3,7 @@
 
 m4_define([dbus_major_version], [1])
 m4_define([dbus_minor_version], [8])
-m4_define([dbus_micro_version], [16])
+m4_define([dbus_micro_version], [18])
 m4_define([dbus_version],
           [dbus_major_version.dbus_minor_version.dbus_micro_version])
 AC_INIT([dbus],[dbus_version],[https://bugs.freedesktop.org/enter_bug.cgi?product=dbus],[dbus])
@@ -37,7 +37,7 @@
 
 ## increment any time the source changes; set to
 ##  0 if you increment CURRENT
-LT_REVISION=11
+LT_REVISION=12
 
 ## increment if any interfaces have been added; set to 0
 ## if any interfaces have been changed or removed. removal has
@@ -122,6 +122,13 @@
     AC_DEFINE(DBUS_CYGWIN,1,[Defined if we run on a cygwin API based system])
 fi
 
+# For best security, assume that all non-Windows platforms can do
+# credentials-passing.
+AS_IF([test "$dbus_win" = yes],
+    [DBUS_SESSION_CONF_MAYBE_AUTH_EXTERNAL="<!--<auth>EXTERNAL</auth>-->"],
+    [DBUS_SESSION_CONF_MAYBE_AUTH_EXTERNAL="<auth>EXTERNAL</auth>"])
+AC_SUBST([DBUS_SESSION_CONF_MAYBE_AUTH_EXTERNAL])
+
 AM_CONDITIONAL(DBUS_WIN, test "$dbus_win" = yes)
 AM_CONDITIONAL(DBUS_WINCE, test "$dbus_wince" = yes)
 AM_CONDITIONAL(DBUS_UNIX, test "$dbus_unix" = yes)
diff -Nru dbus-1.8.16/dbus/dbus-internals.c dbus-1.8.18/dbus/dbus-internals.c
--- dbus-1.8.16/dbus/dbus-internals.c	2015-02-03 15:47:02.000000000 +0000
+++ dbus-1.8.18/dbus/dbus-internals.c	2015-05-14 13:23:25.000000000 +0100
@@ -499,7 +499,7 @@
         {
           VALGRIND_PRINTF_BACKTRACE ("%s %p ref stolen (%s)",
                                      obj_name, obj, why);
-          _dbus_verbose ("%s %p ref stolen (%s)",
+          _dbus_verbose ("%s %p ref stolen (%s)\n",
                          obj_name, obj, why);
         }
       else
@@ -507,7 +507,7 @@
           VALGRIND_PRINTF_BACKTRACE ("%s %p %d -> %d refs (%s)",
                                      obj_name, obj,
                                      old_refcount, new_refcount, why);
-          _dbus_verbose ("%s %p %d -> %d refs (%s)",
+          _dbus_verbose ("%s %p %d -> %d refs (%s)\n",
                          obj_name, obj, old_refcount, new_refcount, why);
         }
     }
diff -Nru dbus-1.8.16/dbus/dbus-marshal-recursive.c dbus-1.8.18/dbus/dbus-marshal-recursive.c
--- dbus-1.8.16/dbus/dbus-marshal-recursive.c	2015-02-03 15:47:02.000000000 +0000
+++ dbus-1.8.18/dbus/dbus-marshal-recursive.c	2015-05-14 13:23:29.000000000 +0100
@@ -149,6 +149,7 @@
              const DBusString  *value_str,
              int                value_pos)
 {
+  _DBUS_ZERO (*reader);
   reader->byte_order = byte_order;
   reader->finished = FALSE;
   reader->type_str = type_str;
@@ -736,11 +737,11 @@
                         const DBusString  *value_str,
                         int                value_pos)
 {
-  reader->klass = &body_reader_class;
-
   reader_init (reader, byte_order, type_str, type_pos,
                value_str, value_pos);
 
+  reader->klass = &body_reader_class;
+
 #if RECURSIVE_MARSHAL_READ_TRACE
   _dbus_verbose ("  type reader %p init type_pos = %d value_pos = %d remaining sig '%s'\n",
                  reader, reader->type_pos, reader->value_pos,
@@ -761,11 +762,11 @@
                                    const DBusString  *type_str,
                                    int                type_pos)
 {
-  reader->klass = &body_types_only_reader_class;
-
   reader_init (reader, DBUS_COMPILER_BYTE_ORDER /* irrelevant */,
                type_str, type_pos, NULL, _DBUS_INT_MAX /* crashes if we screw up */);
 
+  reader->klass = &body_types_only_reader_class;
+
 #if RECURSIVE_MARSHAL_READ_TRACE
   _dbus_verbose ("  type reader %p init types only type_pos = %d remaining sig '%s'\n",
                  reader, reader->type_pos,
@@ -988,6 +989,7 @@
 _dbus_type_reader_recurse (DBusTypeReader *reader,
                            DBusTypeReader *sub)
 {
+  const DBusTypeReaderClass *klass;
   int t;
 
   t = _dbus_first_type_in_signature (reader->type_str, reader->type_pos);
@@ -996,27 +998,27 @@
     {
     case DBUS_TYPE_STRUCT:
       if (reader->klass->types_only)
-        sub->klass = &struct_types_only_reader_class;
+        klass = &struct_types_only_reader_class;
       else
-        sub->klass = &struct_reader_class;
+        klass = &struct_reader_class;
       break;
     case DBUS_TYPE_DICT_ENTRY:
       if (reader->klass->types_only)
-        sub->klass = &dict_entry_types_only_reader_class;
+        klass = &dict_entry_types_only_reader_class;
       else
-        sub->klass = &dict_entry_reader_class;
+        klass = &dict_entry_reader_class;
       break;
     case DBUS_TYPE_ARRAY:
       if (reader->klass->types_only)
-        sub->klass = &array_types_only_reader_class;
+        klass = &array_types_only_reader_class;
       else
-        sub->klass = &array_reader_class;
+        klass = &array_reader_class;
       break;
     case DBUS_TYPE_VARIANT:
       if (reader->klass->types_only)
         _dbus_assert_not_reached ("can't recurse into variant typecode");
       else
-        sub->klass = &variant_reader_class;
+        klass = &variant_reader_class;
       break;
     default:
       _dbus_verbose ("recursing into type %s\n", _dbus_type_to_string (t));
@@ -1028,9 +1030,10 @@
       _dbus_assert_not_reached ("don't yet handle recursing into this type");
     }
 
-  _dbus_assert (sub->klass == all_reader_classes[sub->klass->id]);
+  _dbus_assert (klass == all_reader_classes[klass->id]);
 
-  (* sub->klass->recurse) (sub, reader);
+  (* klass->recurse) (sub, reader);
+  sub->klass = klass;
 
 #if RECURSIVE_MARSHAL_READ_TRACE
   _dbus_verbose ("  type reader %p RECURSED type_pos = %d value_pos = %d remaining sig '%s'\n",
diff -Nru dbus-1.8.16/dbus/dbus-message.c dbus-1.8.18/dbus/dbus-message.c
--- dbus-1.8.16/dbus/dbus-message.c	2015-02-03 15:47:02.000000000 +0000
+++ dbus-1.8.18/dbus/dbus-message.c	2015-05-14 13:23:25.000000000 +0100
@@ -4796,7 +4796,10 @@
     return NULL;
 
   _dbus_message_loader_get_buffer (loader, &buffer);
-  _dbus_string_append_len (buffer, str, len);
+
+  if (!_dbus_string_append_len (buffer, str, len))
+    goto fail_oom;
+
   _dbus_message_loader_return_buffer (loader, buffer);
 
   if (!_dbus_message_loader_queue_messages (loader))
diff -Nru dbus-1.8.16/dbus/dbus-nonce.c dbus-1.8.18/dbus/dbus-nonce.c
--- dbus-1.8.16/dbus/dbus-nonce.c	2015-02-03 15:47:02.000000000 +0000
+++ dbus-1.8.18/dbus/dbus-nonce.c	2015-05-14 13:23:25.000000000 +0100
@@ -74,7 +74,13 @@
         }
       else
         {
-          _dbus_string_append_len(&buffer, _dbus_string_get_const_data (&p), n);
+          if (!_dbus_string_append_len (&buffer, _dbus_string_get_const_data (&p), n))
+            {
+              dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+              _dbus_string_free (&p);
+              _dbus_string_free (&buffer);
+              return FALSE;
+            }
           nleft -= n;
         }
     }
diff -Nru dbus-1.8.16/dbus/dbus-resources.c dbus-1.8.18/dbus/dbus-resources.c
--- dbus-1.8.16/dbus/dbus-resources.c	2015-02-03 15:47:02.000000000 +0000
+++ dbus-1.8.18/dbus/dbus-resources.c	2015-05-14 13:23:25.000000000 +0100
@@ -69,6 +69,7 @@
   DBusCounterNotifyFunction notify_function; /**< notify function */
   void *notify_data; /**< data for notify function */
   dbus_bool_t notify_pending : 1; /**< TRUE if the guard value has been crossed */
+  DBusRMutex *mutex;    /**< Lock on the entire DBusCounter */
 };
 
 /** @} */  /* end of resource limits internals docs */
@@ -95,6 +96,13 @@
 
   counter->refcount = 1;
 
+  _dbus_rmutex_new_at_location (&counter->mutex);
+  if (counter->mutex == NULL)
+  {
+    dbus_free (counter);
+    counter = NULL;
+  }
+
   return counter;
 }
 
@@ -107,10 +115,14 @@
 DBusCounter *
 _dbus_counter_ref (DBusCounter *counter)
 {
+  _dbus_rmutex_lock (counter->mutex);
+
   _dbus_assert (counter->refcount > 0);
   
   counter->refcount += 1;
 
+  _dbus_rmutex_unlock (counter->mutex);
+
   return counter;
 }
 
@@ -123,13 +135,20 @@
 void
 _dbus_counter_unref (DBusCounter *counter)
 {
+  dbus_bool_t last_ref = FALSE;
+
+  _dbus_rmutex_lock (counter->mutex);
+
   _dbus_assert (counter->refcount > 0);
 
   counter->refcount -= 1;
+  last_ref = (counter->refcount == 0);
+
+  _dbus_rmutex_unlock (counter->mutex);
 
-  if (counter->refcount == 0)
+  if (last_ref)
     {
-      
+      _dbus_rmutex_free_at_location (&counter->mutex);
       dbus_free (counter);
     }
 }
@@ -148,7 +167,11 @@
 _dbus_counter_adjust_size (DBusCounter *counter,
                            long         delta)
 {
-  long old = counter->size_value;
+  long old = 0;
+
+  _dbus_rmutex_lock (counter->mutex);
+
+  old = counter->size_value;
 
   counter->size_value += delta;
 
@@ -168,6 +191,8 @@
        (old >= counter->notify_size_guard_value &&
         counter->size_value < counter->notify_size_guard_value)))
     counter->notify_pending = TRUE;
+
+  _dbus_rmutex_unlock (counter->mutex);
 }
 
 /**
@@ -181,11 +206,20 @@
 void
 _dbus_counter_notify (DBusCounter *counter)
 {
+  DBusCounterNotifyFunction notify_function = NULL;
+  void *notify_data = NULL;
+
+  _dbus_rmutex_lock (counter->mutex);
   if (counter->notify_pending)
     {
       counter->notify_pending = FALSE;
-      (* counter->notify_function) (counter, counter->notify_data);
+      notify_function = counter->notify_function;
+      notify_data = counter->notify_data;
     }
+  _dbus_rmutex_unlock (counter->mutex);
+
+  if (notify_function != NULL)
+    (* notify_function) (counter, notify_data);
 }
 
 /**
@@ -202,7 +236,11 @@
 _dbus_counter_adjust_unix_fd (DBusCounter *counter,
                               long         delta)
 {
-  long old = counter->unix_fd_value;
+  long old = 0;
+
+  _dbus_rmutex_lock (counter->mutex);
+
+  old = counter->unix_fd_value;
   
   counter->unix_fd_value += delta;
 
@@ -222,6 +260,8 @@
        (old >= counter->notify_unix_fd_guard_value &&
         counter->unix_fd_value < counter->notify_unix_fd_guard_value)))
     counter->notify_pending = TRUE;
+
+  _dbus_rmutex_unlock (counter->mutex);
 }
 
 /**
@@ -266,11 +306,13 @@
                           DBusCounterNotifyFunction  function,
                           void                      *user_data)
 {
+  _dbus_rmutex_lock (counter->mutex);
   counter->notify_size_guard_value = size_guard_value;
   counter->notify_unix_fd_guard_value = unix_fd_guard_value;
   counter->notify_function = function;
   counter->notify_data = user_data;
   counter->notify_pending = FALSE;
+  _dbus_rmutex_unlock (counter->mutex);
 }
 
 #ifdef DBUS_ENABLE_STATS
diff -Nru dbus-1.8.16/dbus/dbus-server.c dbus-1.8.18/dbus/dbus-server.c
--- dbus-1.8.16/dbus/dbus-server.c	2015-02-03 15:47:02.000000000 +0000
+++ dbus-1.8.18/dbus/dbus-server.c	2015-05-14 13:23:25.000000000 +0100
@@ -1043,7 +1043,10 @@
     {
       copy = _dbus_dup_string_array (mechanisms);
       if (copy == NULL)
-        return FALSE;
+        {
+          SERVER_UNLOCK (server);
+          return FALSE;
+        }
     }
   else
     copy = NULL;
diff -Nru dbus-1.8.16/dbus/dbus-transport.c dbus-1.8.18/dbus/dbus-transport.c
--- dbus-1.8.16/dbus/dbus-transport.c	2015-02-03 15:47:02.000000000 +0000
+++ dbus-1.8.18/dbus/dbus-transport.c	2015-05-14 13:23:25.000000000 +0100
@@ -63,6 +63,7 @@
 {
   DBusTransport *transport = user_data;
 
+  _dbus_connection_lock (transport->connection);
   _dbus_transport_ref (transport);
 
 #if 0
@@ -77,12 +78,11 @@
    */
   if (transport->vtable->live_messages_changed)
     {
-      _dbus_connection_lock (transport->connection);
       (* transport->vtable->live_messages_changed) (transport);
-      _dbus_connection_unlock (transport->connection);
     }
 
   _dbus_transport_unref (transport);
+  _dbus_connection_unlock (transport->connection);
 }
 
 /**
diff -Nru dbus-1.8.16/debian/changelog dbus-1.8.18/debian/changelog
--- dbus-1.8.16/debian/changelog	2015-02-04 20:15:37.000000000 +0000
+++ dbus-1.8.18/debian/changelog	2015-05-14 13:57:50.000000000 +0100
@@ -1,3 +1,14 @@
+dbus (1.8.18-0+deb8u1) jessie; urgency=medium
+
+  * New upstream bugfix release
+    - Hardening: lock down the session bus to only allow EXTERNAL auth by
+      default, the same as the system bus. This avoids allowing
+      DBUS_COOKIE_SHA1, which can end up using a predictable random source
+      on systems where /dev/urandom is unavailable or dbus-daemon runs out
+      of memory. See the upstream NEWS for more details.
+
+ -- Simon McVittie <smcv@debian.org>  Thu, 14 May 2015 13:52:50 +0100
+
 dbus (1.8.16-1) unstable; urgency=high
 
   * New upstream release fixes a local denial of service
diff -Nru dbus-1.8.16/NEWS dbus-1.8.18/NEWS
--- dbus-1.8.16/NEWS	2015-02-04 16:48:51.000000000 +0000
+++ dbus-1.8.18/NEWS	2015-05-14 13:23:29.000000000 +0100
@@ -1,3 +1,50 @@
+D-Bus 1.8.18 (2015-05-14)
+==
+
+The “unicorn rifts” release.
+
+Security hardening:
+
+• On Unix platforms, change the default configuration for the session bus
+  to only allow EXTERNAL authentication (secure kernel-mediated
+  credentials-passing), as was already done for the system bus.
+
+  This avoids falling back to DBUS_COOKIE_SHA1, which relies on strongly
+  unpredictable pseudo-random numbers; under certain circumstances
+  (/dev/urandom unreadable or malloc() returns NULL), dbus could
+  fall back to using rand(), which does not have the desired unpredictability.
+  The fallback to rand() has not been changed in this stable-branch since
+  the necessary code changes for correct error-handling are rather intrusive.
+
+  If you are using D-Bus over the (unencrypted!) tcp: or nonce-tcp: transport,
+  in conjunction with DBUS_COOKIE_SHA1 and a shared home directory using
+  NFS or similar, you will need to reconfigure the session bus to accept
+  DBUS_COOKIE_SHA1 by commenting out the <auth> element. This configuration
+  is not recommended.
+
+  (fd.o #90414, Simon McVittie)
+
+Other fixes:
+
+• Add locking to DBusCounter's reference count and notify function
+  (fd.o #89297, Adrian Szyndela)
+
+• Ensure that DBusTransport's reference count is protected by the
+  corresponding DBusConnection's lock (fd.o #90312, Adrian Szyndela)
+
+• On Windows, listen on the same port for IPv4 and IPv6 (previously
+  broken by an endianness mistake), and fix a failure to bind TCP
+  sockets on approximately 1 attempt in 256 (fd.o #87999, Ralf Habacker)
+
+• Correctly release DBusServer mutex before early-return if we run out
+  of memory while copying authentication mechanisms (fd.o #90004,
+  Ralf Habacker)
+
+• Fix some missing \n in verbose (debug log) messages (fd.o #90004,
+  Ralf Habacker)
+
+• Clean up some memory leaks in test code (fd.o #90004, Ralf Habacker)
+
 D-Bus 1.8.16 (2015-02-09)
 ==
 
diff -Nru dbus-1.8.16/test/Makefile.am dbus-1.8.18/test/Makefile.am
--- dbus-1.8.16/test/Makefile.am	2015-02-03 15:47:02.000000000 +0000
+++ dbus-1.8.18/test/Makefile.am	2015-05-14 13:23:25.000000000 +0100
@@ -119,6 +119,10 @@
 test_syslog_CPPFLAGS = $(static_cppflags)
 test_syslog_LDADD = libdbus-testutils-internal.la $(GLIB_LIBS)
 
+manual_tcp_SOURCES = manual-tcp.c
+manual_tcp_CPPFLAGS = $(static_cppflags)
+manual_tcp_LDADD = $(top_builddir)/dbus/libdbus-internal.la
+
 EXTRA_DIST = dbus-test-runner
 
 testexecdir = $(libdir)/dbus-1.0/test
@@ -130,6 +134,7 @@
 	test-printf \
 	$(NULL)
 installable_manual_tests = \
+	manual-tcp \
 	$(NULL)
 
 if DBUS_WITH_GLIB
diff -Nru dbus-1.8.16/test/manual-tcp.c dbus-1.8.18/test/manual-tcp.c
--- dbus-1.8.16/test/manual-tcp.c	1970-01-01 01:00:00.000000000 +0100
+++ dbus-1.8.18/test/manual-tcp.c	2015-05-14 13:23:04.000000000 +0100
@@ -0,0 +1,46 @@
+/*
+ * Simple manual tcp check
+ *
+ * supports:
+ * - server listening check
+ *
+ * syntax:  manual-tcp [<ipv4>|<ipv6>]
+ *
+*/
+
+#include "config.h"
+#include "dbus/dbus-server-socket.h"
+
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+    DBusServer      *server;
+    DBusError       error;
+    int result = 0;
+    int i;
+
+    char *family = NULL;
+
+    if (argc == 2)
+        family = argv[1];
+
+    for (i = 0; i < 1000; i++)
+    {
+        dbus_error_init (&error);
+        server = _dbus_server_new_for_tcp_socket ("localhost", "localhost", "0", family, &error, FALSE);
+        if (server == NULL)
+          {
+            printf("%d: %s %s\n",i, error.name, error.message);
+            dbus_error_free(&error);
+            result = -1;
+          }
+        else {
+            printf("%d: %s \n",i, dbus_server_get_address(server));
+            dbus_server_disconnect(server);
+            dbus_server_unref(server);
+        }
+    }
+    return result;
+}
diff -Nru dbus-1.8.16/test/relay.c dbus-1.8.18/test/relay.c
--- dbus-1.8.16/test/relay.c	2015-02-03 15:47:02.000000000 +0000
+++ dbus-1.8.18/test/relay.c	2015-05-14 13:23:25.000000000 +0100
@@ -273,6 +273,7 @@
 {
   if (f->left_client_conn != NULL)
     {
+      test_connection_shutdown(NULL, f->left_client_conn);
       dbus_connection_close (f->left_client_conn);
       dbus_connection_unref (f->left_client_conn);
       f->left_client_conn = NULL;
@@ -280,6 +281,7 @@
 
   if (f->right_client_conn != NULL)
     {
+      test_connection_shutdown(NULL, f->right_client_conn);
       dbus_connection_close (f->right_client_conn);
       dbus_connection_unref (f->right_client_conn);
       f->right_client_conn = NULL;
@@ -287,6 +289,7 @@
 
   if (f->left_server_conn != NULL)
     {
+      test_connection_shutdown(NULL, f->left_server_conn);
       dbus_connection_close (f->left_server_conn);
       dbus_connection_unref (f->left_server_conn);
       f->left_server_conn = NULL;
@@ -294,6 +297,7 @@
 
   if (f->right_server_conn != NULL)
     {
+      test_connection_shutdown(NULL, f->right_server_conn);
       dbus_connection_close (f->right_server_conn);
       dbus_connection_unref (f->right_server_conn);
       f->right_server_conn = NULL;

Reply to: