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

Bug#962067: buster-pu: package dbus/1.12.18-0+deb10u1



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

dbus 1.12.18 fixes a local denial of service vulnerability for which
the Security Team have indicated they do not intend to issue a DSA.

If possible I would like to use upstream 1.12.x versions of dbus for
buster (security and) stable updates, similar to the policy used in
stretch and jessie. This branch includes security fixes and selected
non-intrusive bug fixes (and unfortunately also the usual Autotools
noise).

Proposed diff (modulo `dch -r -D buster`) attached, filtered through:

git diff --stat -p origin/debian/buster.. | \
filterdiff -p1 \
--exclude=Makefile.in --exclude='**/Makefile.in' \
--exclude=aclocal.m4 \
--exclude=aminclude_static.am \
--exclude=build-aux/compile \
--exclude=build-aux/depcomp \
--exclude=build-aux/install-sh \
--exclude=build-aux/ltmain.sh \
--exclude=build-aux/missing \
--exclude=build-aux/tap-driver.sh \
--exclude=configure \
--exclude=m4/libtool.m4

Thanks,
    smcv
 Makefile.in                                        |  42 ++--
 NEWS                                               |  39 ++++
 aclocal.m4                                         | 240 ++++++---------------
 aminclude_static.am                                |   2 +-
 build-aux/compile                                  |   6 +-
 build-aux/depcomp                                  |   2 +-
 build-aux/install-sh                               |  13 +-
 build-aux/ltmain.sh                                |  10 +-
 build-aux/missing                                  |   2 +-
 build-aux/tap-driver.sh                            |   2 +-
 bus/Makefile.in                                    |   6 +-
 bus/connection.c                                   |   7 +-
 cmake/tools/CMakeLists.txt                         |   1 +
 configure                                          |  70 +++---
 configure.ac                                       |   4 +-
 dbus/Makefile.in                                   |   6 +-
 dbus/dbus-message.c                                |  14 +-
 dbus/dbus-sysdeps-unix.c                           |  32 +--
 debian/changelog                                   |  11 +
 debian/gbp.conf                                    |   2 +-
 ...-Don-t-test-fd-limits-if-in-an-unprivileg.patch |  83 -------
 debian/patches/series                              |   1 -
 doc/Makefile.in                                    |   6 +-
 doc/dbus-daemon.1.xml.in                           |   2 +-
 doc/dbus-send.1.xml.in                             |  12 +-
 m4/libtool.m4                                      |   6 +-
 test/Makefile.in                                   |   6 +-
 test/dbus-daemon.c                                 |  30 ++-
 test/fdpass.c                                      |  14 ++
 test/name-test/Makefile.in                         |   4 +-
 tools/Makefile.in                                  |   4 +-
 31 files changed, 314 insertions(+), 365 deletions(-)

diff --git a/NEWS b/NEWS
index 07a933a4..a38c5992 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,42 @@
+dbus 1.12.18 (2020-06-02)
+=========================
+
+The “telepathic vines” release.
+
+Denial of service fixes:
+
+• CVE-2020-12049: If a message contains more file descriptors than can
+  be sent, close those that did get through before reporting error.
+  Previously, a local attacker could cause the system dbus-daemon (or
+  another system service with its own DBusServer) to run out of file
+  descriptors, by repeatedly connecting to the server and sending fds that
+  would get leaked.
+  Thanks to Kevin Backhouse of GitHub Security Lab.
+  (dbus#294, GHSL-2020-057; Simon McVittie)
+
+Other fixes:
+
+• Fix a crash when the dbus-daemon is terminated while one or more
+  monitors are active (dbus#291, dbus!140; Simon McVittie)
+
+• The dbus-send(1) man page now documents --bus and --peer instead of
+  the old --address synonym for --peer, which has been deprecated since
+  the introduction of --bus and --peer in 1.7.6
+  (fd.o #48816, dbus!115; Chris Morin)
+
+• Fix a wrong environment variable name in dbus-daemon(1)
+  (dbus#275, dbus!122; Mubin, Philip Withnall)
+
+• Fix formatting of dbus_message_append_args example
+  (dbus!126, Felipe Franciosi)
+
+• Avoid a test failure on Linux when built in a container as uid 0, but
+  without the necessary privileges to increase resource limits
+  (dbus!58, Debian #908092; Simon McVittie)
+
+• When building with CMake, cope with libX11 in a non-standard location
+  (dbus!129, Tuomo Rinne)
+
 dbus 1.12.16 (2019-06-11)
 =========================
 
diff --git a/bus/connection.c b/bus/connection.c
index 53605fa3..b3583433 100644
--- a/bus/connection.c
+++ b/bus/connection.c
@@ -537,9 +537,6 @@ bus_connections_unref (BusConnections *connections)
 
       _dbus_assert (connections->n_incomplete == 0);
 
-      /* drop all monitors */
-      _dbus_list_clear (&connections->monitors);
-
       /* drop all real connections */
       while (connections->completed != NULL)
         {
@@ -555,6 +552,10 @@ bus_connections_unref (BusConnections *connections)
 
       _dbus_assert (connections->n_completed == 0);
 
+      /* disconnecting all the connections should have emptied the list of
+       * monitors (each link is removed in bus_connection_disconnected) */
+      _dbus_assert (connections->monitors == NULL);
+
       bus_expire_list_free (connections->pending_replies);
       
       _dbus_loop_remove_timeout (bus_context_get_loop (connections->context),
diff --git a/cmake/tools/CMakeLists.txt b/cmake/tools/CMakeLists.txt
index c05ced43..4678bddf 100644
--- a/cmake/tools/CMakeLists.txt
+++ b/cmake/tools/CMakeLists.txt
@@ -48,6 +48,7 @@ set (dbus_launch_SOURCES
      ${dbus_launch_SOURCES}
      ../../tools/dbus-launch-x11.c
 )
+include_directories(${X11_INCLUDE_DIR})
 endif(DBUS_BUILD_X11)
 
 set (dbus_cleanup_sockets_SOURCES
diff --git a/configure.ac b/configure.ac
index d1e3a29f..0601c421 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@ AC_PREREQ([2.63])
 
 m4_define([dbus_major_version], [1])
 m4_define([dbus_minor_version], [12])
-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])
@@ -42,7 +42,7 @@ LT_CURRENT=22
 
 ## 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
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
index 43b3a9fb..84d8c0ca 100644
--- a/dbus/dbus-message.c
+++ b/dbus/dbus-message.c
@@ -1773,10 +1773,16 @@ dbus_message_get_type (DBusMessage *message)
  * To append an array of fixed-length basic types (except Unix file
  * descriptors), pass in the DBUS_TYPE_ARRAY typecode, the element
  * typecode, the address of the array pointer, and a 32-bit integer
- * giving the number of elements in the array. So for example: @code
- * const dbus_int32_t array[] = { 1, 2, 3 }; const dbus_int32_t
- * *v_ARRAY = array; dbus_message_append_args (message,
- * DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY, 3, DBUS_TYPE_INVALID);
+ * giving the number of elements in the array. So for example:
+ *
+ * @code
+ *
+ * const dbus_int32_t array[] = { 1, 2, 3 };
+ * const dbus_int32_t *v_ARRAY = array;
+ * dbus_message_append_args (message,
+ *                           DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY, 3,
+ *                           DBUS_TYPE_INVALID);
+ *
  * @endcode
  *
  * This function does not support arrays of Unix file descriptors. If
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index e8cd5b33..f9dc2a6e 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -435,18 +435,6 @@ _dbus_read_socket_with_unix_fds (DBusSocket        fd,
       struct cmsghdr *cm;
       dbus_bool_t found = FALSE;
 
-      if (m.msg_flags & MSG_CTRUNC)
-        {
-          /* Hmm, apparently the control data was truncated. The bad
-             thing is that we might have completely lost a couple of fds
-             without chance to recover them. Hence let's treat this as a
-             serious error. */
-
-          errno = ENOSPC;
-          _dbus_string_set_length (buffer, start);
-          return -1;
-        }
-
       for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
         if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
           {
@@ -501,6 +489,26 @@ _dbus_read_socket_with_unix_fds (DBusSocket        fd,
       if (!found)
         *n_fds = 0;
 
+      if (m.msg_flags & MSG_CTRUNC)
+        {
+          unsigned int i;
+
+          /* Hmm, apparently the control data was truncated. The bad
+             thing is that we might have completely lost a couple of fds
+             without chance to recover them. Hence let's treat this as a
+             serious error. */
+
+          /* We still need to close whatever fds we *did* receive,
+           * otherwise they'll never get closed. (CVE-2020-12049) */
+          for (i = 0; i < *n_fds; i++)
+            close (fds[i]);
+
+          *n_fds = 0;
+          errno = ENOSPC;
+          _dbus_string_set_length (buffer, start);
+          return -1;
+        }
+
       /* put length back (doesn't actually realloc) */
       _dbus_string_set_length (buffer, start + bytes_read);
 
diff --git a/debian/changelog b/debian/changelog
index 6df1006a..62399ac7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,14 @@
+dbus (1.12.18-0+deb10u1) UNRELEASED; urgency=medium
+
+  * New upstream stable release
+    - CVE-2020-12049: Prevent a denial of service attack in which a local
+      user can make the system dbus-daemon run out of file descriptors
+    - d/p/dbus-daemon-test-Don-t-test-fd-limits-if-in-an-unprivileg.patch:
+      Drop patch, applied upstream.
+  * d/gbp.conf: Configure for debian/buster
+
+ -- Simon McVittie <smcv@debian.org>  Tue, 02 Jun 2020 16:57:42 +0100
+
 dbus (1.12.16-1) unstable; urgency=medium
 
   * New upstream stable release
diff --git a/debian/gbp.conf b/debian/gbp.conf
index 1a6fdcb6..0c5a3970 100644
--- a/debian/gbp.conf
+++ b/debian/gbp.conf
@@ -1,5 +1,5 @@
 [DEFAULT]
 pristine-tar = True
-debian-branch = debian/master
+debian-branch = debian/buster
 upstream-branch = upstream/1.12.x
 patch-numbers = False
diff --git a/debian/patches/dbus-daemon-test-Don-t-test-fd-limits-if-in-an-unprivileg.patch b/debian/patches/dbus-daemon-test-Don-t-test-fd-limits-if-in-an-unprivileg.patch
deleted file mode 100644
index af9415c2..00000000
+++ /dev/null
@@ -1,83 +0,0 @@
-From: Simon McVittie <smcv@collabora.com>
-Date: Tue, 4 Dec 2018 12:09:26 +0000
-Subject: dbus-daemon test: Don't test fd limits if in an unprivileged
- container
-
-In an unprivileged container, uid 0 doesn't have CAP_SYS_RESOURCE, so
-we can't expect the dbus-daemon to be able to escalate its fd limit.
-
-This can be reproduced using bubblewrap:
-
-    sudo bwrap \
-        --cap-drop CAP_SYS_RESOURCE \
-        --ro-bind / / \
-        --dev /dev \
-    env \
-        DBUS_TEST_DAEMON=.../bus/dbus-daemon \
-        DBUS_TEST_DATA=.../test/data \
-    .../test/test-dbus-daemon \
-        -p /fd-limit \
-        --verbose
-
-Bug-Debian: https://bugs.debian.org/908092
-Forwarded: https://gitlab.freedesktop.org/dbus/dbus/merge_requests/58
----
- test/dbus-daemon.c | 30 ++++++++++++++++++++++++++++--
- 1 file changed, 28 insertions(+), 2 deletions(-)
-
-diff --git a/test/dbus-daemon.c b/test/dbus-daemon.c
-index 7d3bb4b..d753d83 100644
---- a/test/dbus-daemon.c
-+++ b/test/dbus-daemon.c
-@@ -2040,6 +2040,7 @@ test_fd_limit (Fixture *f,
- {
- #ifdef HAVE_PRLIMIT
-   struct rlimit lim;
-+  struct rlimit new_limit;
-   const struct passwd *pwd = NULL;
- #endif
- 
-@@ -2067,7 +2068,7 @@ test_fd_limit (Fixture *f,
-     }
- 
-   if (prlimit (getpid (), RLIMIT_NOFILE, NULL, &lim) < 0)
--    g_error ("prlimit(): %s", g_strerror (errno));
-+    g_error ("get prlimit (self): %s", g_strerror (errno));
- 
-   g_test_message ("our RLIMIT_NOFILE: rlim_cur: %ld, rlim_max: %ld",
-                   (long) lim.rlim_cur, (long) lim.rlim_max);
-@@ -2079,8 +2080,33 @@ test_fd_limit (Fixture *f,
-       return;
-     }
- 
-+  new_limit = lim;
-+  new_limit.rlim_cur = DESIRED_RLIMIT;
-+  new_limit.rlim_max = DESIRED_RLIMIT;
-+
-+  /* Try to increase the rlimit ourselves. If we're root in an
-+   * unprivileged Linux container, then we won't have CAP_SYS_RESOURCE
-+   * and this will fail with EPERM. If so, the dbus-daemon wouldn't be
-+   * able to increase its rlimit either. */
-+  if (prlimit (getpid (), RLIMIT_NOFILE, &new_limit, NULL) < 0)
-+    {
-+      gchar *message;
-+
-+      message = g_strdup_printf ("Cannot test, we cannot change the rlimit so "
-+                                 "presumably neither can the dbus-daemon: %s",
-+                                 g_strerror (errno));
-+      g_test_skip (message);
-+      g_free (message);
-+      return;
-+    }
-+
-+  /* Immediately put our original limit back so it won't interfere with
-+   * subsequent tests. This should always succeed. */
-+  if (prlimit (getpid (), RLIMIT_NOFILE, &lim, NULL) < 0)
-+    g_error ("Cannot restore our original limits: %s", g_strerror (errno));
-+
-   if (prlimit (f->daemon_pid, RLIMIT_NOFILE, NULL, &lim) < 0)
--    g_error ("prlimit(): %s", g_strerror (errno));
-+    g_error ("get prlimit (dbus-daemon): %s", g_strerror (errno));
- 
-   g_test_message ("dbus-daemon's RLIMIT_NOFILE: rlim_cur: %ld, rlim_max: %ld",
-                   (long) lim.rlim_cur, (long) lim.rlim_max);
diff --git a/debian/patches/series b/debian/patches/series
index 4b9ab8b6..06b98425 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,2 @@
-dbus-daemon-test-Don-t-test-fd-limits-if-in-an-unprivileg.patch
 debian/session.conf-system.conf-include-legacy-files-as-.dpkg-ba.patch
 debian/tests-Multiply-timeouts-by-20-on-riscv64.patch
diff --git a/doc/dbus-daemon.1.xml.in b/doc/dbus-daemon.1.xml.in
index 960da080..b6cda2f6 100644
--- a/doc/dbus-daemon.1.xml.in
+++ b/doc/dbus-daemon.1.xml.in
@@ -267,7 +267,7 @@ DBUS_STARTER_BUS_TYPE environment variable will be set to "session"
 and the DBUS_SESSION_BUS_ADDRESS environment variable will be set
 to the address of the session bus.  Likewise, if the type of the
 message bus is "system", then the DBUS_STARTER_BUS_TYPE environment
-variable will be set to "system" and the DBUS_SESSION_BUS_ADDRESS
+variable will be set to "system" and the DBUS_SYSTEM_BUS_ADDRESS
 environment variable will be set to the address of the system bus
 (which is normally well known anyway).</para>
 
diff --git a/doc/dbus-send.1.xml.in b/doc/dbus-send.1.xml.in
index 271435ca..34c4b99e 100644
--- a/doc/dbus-send.1.xml.in
+++ b/doc/dbus-send.1.xml.in
@@ -21,7 +21,7 @@
 <refsynopsisdiv id='synopsis'>
 <cmdsynopsis>
   <command>dbus-send</command>
-    <group choice='opt'><arg choice='plain'>--system </arg><arg choice='plain'>--session </arg><arg choice='plain'>--address=<replaceable>ADDRESS</replaceable></arg></group>
+  <group choice='opt'><arg choice='plain'>--system </arg><arg choice='plain'>--session </arg><arg choice='plain'>--bus=<replaceable>ADDRESS</replaceable></arg><arg choice='plain'>--peer=<replaceable>ADDRESS</replaceable></arg></group>
     <arg choice='opt'>--dest=<replaceable>NAME</replaceable></arg>
     <arg choice='opt'><arg choice='plain'>--print-reply </arg><arg choice='opt'><replaceable>=literal</replaceable></arg></arg>
     <arg choice='opt'>--reply-timeout=<replaceable>MSEC</replaceable></arg>
@@ -137,9 +137,15 @@ The default is implementation&hyphen;defined, typically 25 seconds.</para>
   </listitem>
   </varlistentry>
   <varlistentry>
-  <term><option>--address=</option><replaceable>ADDRESS</replaceable></term>
+  <term><option>--bus=</option><replaceable>ADDRESS</replaceable></term>
   <listitem>
-<para>Send to <replaceable>ADDRESS</replaceable>.</para>
+<para>Register on a message bus at <replaceable>ADDRESS</replaceable>, typically a <command>dbus-daemon</command>.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><option>--peer=</option><replaceable>ADDRESS</replaceable></term>
+  <listitem>
+<para>Send to a non-message-bus D-Bus server at <replaceable>ADDRESS</replaceable>. In this case <command>dbus-send</command> will not call the <literal>Hello</literal> method.</para>
   </listitem>
   </varlistentry>
   <varlistentry>
diff --git a/test/dbus-daemon.c b/test/dbus-daemon.c
index 7d3bb4b2..d753d831 100644
--- a/test/dbus-daemon.c
+++ b/test/dbus-daemon.c
@@ -2040,6 +2040,7 @@ test_fd_limit (Fixture *f,
 {
 #ifdef HAVE_PRLIMIT
   struct rlimit lim;
+  struct rlimit new_limit;
   const struct passwd *pwd = NULL;
 #endif
 
@@ -2067,7 +2068,7 @@ test_fd_limit (Fixture *f,
     }
 
   if (prlimit (getpid (), RLIMIT_NOFILE, NULL, &lim) < 0)
-    g_error ("prlimit(): %s", g_strerror (errno));
+    g_error ("get prlimit (self): %s", g_strerror (errno));
 
   g_test_message ("our RLIMIT_NOFILE: rlim_cur: %ld, rlim_max: %ld",
                   (long) lim.rlim_cur, (long) lim.rlim_max);
@@ -2079,8 +2080,33 @@ test_fd_limit (Fixture *f,
       return;
     }
 
+  new_limit = lim;
+  new_limit.rlim_cur = DESIRED_RLIMIT;
+  new_limit.rlim_max = DESIRED_RLIMIT;
+
+  /* Try to increase the rlimit ourselves. If we're root in an
+   * unprivileged Linux container, then we won't have CAP_SYS_RESOURCE
+   * and this will fail with EPERM. If so, the dbus-daemon wouldn't be
+   * able to increase its rlimit either. */
+  if (prlimit (getpid (), RLIMIT_NOFILE, &new_limit, NULL) < 0)
+    {
+      gchar *message;
+
+      message = g_strdup_printf ("Cannot test, we cannot change the rlimit so "
+                                 "presumably neither can the dbus-daemon: %s",
+                                 g_strerror (errno));
+      g_test_skip (message);
+      g_free (message);
+      return;
+    }
+
+  /* Immediately put our original limit back so it won't interfere with
+   * subsequent tests. This should always succeed. */
+  if (prlimit (getpid (), RLIMIT_NOFILE, &lim, NULL) < 0)
+    g_error ("Cannot restore our original limits: %s", g_strerror (errno));
+
   if (prlimit (f->daemon_pid, RLIMIT_NOFILE, NULL, &lim) < 0)
-    g_error ("prlimit(): %s", g_strerror (errno));
+    g_error ("get prlimit (dbus-daemon): %s", g_strerror (errno));
 
   g_test_message ("dbus-daemon's RLIMIT_NOFILE: rlim_cur: %ld, rlim_max: %ld",
                   (long) lim.rlim_cur, (long) lim.rlim_max);
diff --git a/test/fdpass.c b/test/fdpass.c
index 4a3edc4e..8bad675f 100644
--- a/test/fdpass.c
+++ b/test/fdpass.c
@@ -50,6 +50,14 @@
 
 #include "test-utils-glib.h"
 
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
+#include <dbus/dbus-message-internal.h>
+#else
+typedef struct _DBusInitialFDs DBusInitialFDs;
+#define _dbus_check_fdleaks_enter() NULL
+#define _dbus_check_fdleaks_leave(fds) do {} while (0)
+#endif
+
 /* Arbitrary; included here to avoid relying on the default */
 #define MAX_MESSAGE_UNIX_FDS 20
 /* This test won't work on Linux unless this is true. */
@@ -92,6 +100,7 @@ typedef struct {
     GQueue messages;
 
     int fd_before;
+    DBusInitialFDs *initial_fds;
 } Fixture;
 
 static void oom (const gchar *doing) G_GNUC_NORETURN;
@@ -176,6 +185,8 @@ test_connect (Fixture *f,
   if (f->skip)
     return;
 
+  f->initial_fds = _dbus_check_fdleaks_enter ();
+
   g_assert (f->left_server_conn == NULL);
   g_assert (f->right_server_conn == NULL);
 
@@ -871,6 +882,9 @@ teardown (Fixture *f,
   if (f->fd_before >= 0 && close (f->fd_before) < 0)
     g_error ("%s", g_strerror (errno));
 #endif
+
+  if (f->initial_fds != NULL)
+    _dbus_check_fdleaks_leave (f->initial_fds);
 }
 
 int

Reply to: