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

Bug#768992: marked as done (unblock: dbus/1.8.10-1)



Your message dated Wed, 12 Nov 2014 14:49:12 +0100
with message-id <20141112134912.GW2077@betterave.cristau.org>
and subject line Re: Bug#768992: unblock: dbus/1.8.10-1
has caused the Debian Bug report #768992,
regarding unblock: dbus/1.8.10-1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
768992: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=768992
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package dbus to pick up the denial of service fix
that I just released (CVE-2014-7824):

unblock dbus/1.8.10-1

The new upstream release does not introduce any changes other than
the security fix and the new version metadata, so I imported it
as-is rather than doing a trivial "backport".

I attach a filtered source debdiff with autotools noise excluded
(we re-generate the autotools files with autoreconf during the build
anyway), and a full source debdiff.

Thanks,
    S
diffstat for dbus-1.8.8 dbus-1.8.10

 NEWS                          |   12 +++
 aclocal.m4                    |    7 --
 bus/activation.c              |   28 +++++++-
 bus/bus.c                     |   50 +++++++++++---
 bus/bus.h                     |    1 
 configure                     |   30 ++++----
 configure.ac                  |    4 -
 dbus/dbus-sysdeps-util-unix.c |  147 +++++++++++++++++++++++++++++++++---------
 dbus/dbus-sysdeps-util-win.c  |   35 +++++++++-
 dbus/dbus-sysdeps.h           |   11 ++-
 debian/changelog              |   12 +++
 debian/dbus.init              |    2 
 doc/Makefile.in               |    2 
 13 files changed, 274 insertions(+), 67 deletions(-)

diff -Nru dbus-1.8.8/aclocal.m4 dbus-1.8.10/aclocal.m4
--- dbus-1.8.8/aclocal.m4	2014-09-15 12:43:13.000000000 +0100
+++ dbus-1.8.10/aclocal.m4	2014-11-06 15:40:17.000000000 +0000
@@ -103,10 +103,9 @@
 # configured tree to be moved without reconfiguration.
 
 AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
 ])
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
diff -Nru dbus-1.8.8/bus/activation.c dbus-1.8.10/bus/activation.c
--- dbus-1.8.8/bus/activation.c	2014-09-12 12:52:11.000000000 +0100
+++ dbus-1.8.10/bus/activation.c	2014-11-06 15:30:51.000000000 +0000
@@ -1688,6 +1688,31 @@
   return retval;
 }
 
+static void
+child_setup (void *user_data)
+{
+#ifdef DBUS_UNIX
+  BusActivation *activation = user_data;
+  DBusRLimit *initial_fd_limit;
+  DBusError error;
+
+  dbus_error_init (&error);
+  initial_fd_limit = bus_context_get_initial_fd_limit (activation->context);
+
+  if (initial_fd_limit != NULL &&
+      !_dbus_rlimit_restore_fd_limit (initial_fd_limit, &error))
+    {
+      /* unfortunately we don't actually know the service name here */
+      bus_context_log (activation->context,
+                       DBUS_SYSTEM_LOG_INFO,
+                       "Failed to reset fd limit before activating "
+                       "service: %s: %s",
+                       error.name, error.message);
+    }
+#endif
+}
+
+
 dbus_bool_t
 bus_activation_activate_service (BusActivation  *activation,
                                  DBusConnection *connection,
@@ -2121,7 +2146,8 @@
                                           service_name,
                                           argv,
                                           envp,
-                                          NULL, activation,
+                                          child_setup,
+                                          activation,
                                           &tmp_error))
     {
       _dbus_verbose ("Failed to spawn child\n");
diff -Nru dbus-1.8.8/bus/bus.c dbus-1.8.10/bus/bus.c
--- dbus-1.8.8/bus/bus.c	2014-09-15 12:29:28.000000000 +0100
+++ dbus-1.8.10/bus/bus.c	2014-11-06 15:30:51.000000000 +0000
@@ -64,6 +64,7 @@
   BusPolicy *policy;
   BusMatchmaker *matchmaker;
   BusLimits limits;
+  DBusRLimit *initial_fd_limit;
   unsigned int fork : 1;
   unsigned int syslog : 1;
   unsigned int keep_umask : 1;
@@ -659,19 +660,38 @@
 static void
 raise_file_descriptor_limit (BusContext      *context)
 {
+#ifdef DBUS_UNIX
+  DBusError error = DBUS_ERROR_INIT;
 
-  /* I just picked this out of thin air; we need some extra
-   * descriptors for things like any internal pipes we create,
-   * inotify, connections to SELinux, etc.
-   */
-  unsigned int arbitrary_extra_fds = 32;
-  unsigned int limit;
+  /* we only do this once */
+  if (context->initial_fd_limit != NULL)
+    return;
 
-  limit = context->limits.max_completed_connections +
-    context->limits.max_incomplete_connections
-    + arbitrary_extra_fds;
+  context->initial_fd_limit = _dbus_rlimit_save_fd_limit (&error);
 
-  _dbus_request_file_descriptor_limit (limit);
+  if (context->initial_fd_limit == NULL)
+    {
+      bus_context_log (context, DBUS_SYSTEM_LOG_INFO,
+                       "%s: %s", error.name, error.message);
+      dbus_error_free (&error);
+      return;
+    }
+
+  /* We used to compute a suitable rlimit based on the configured number
+   * of connections, but that breaks down as soon as we allow fd-passing,
+   * because each connection is allowed to pass 64 fds to us, and if
+   * they all did, we'd hit kernel limits. We now hard-code 64k as a
+   * good limit, like systemd does: that's enough to avoid DoS from
+   * anything short of multiple uids conspiring against us.
+   */
+  if (!_dbus_rlimit_raise_fd_limit_if_privileged (65536, &error))
+    {
+      bus_context_log (context, DBUS_SYSTEM_LOG_INFO,
+                       "%s: %s", error.name, error.message);
+      dbus_error_free (&error);
+      return;
+    }
+#endif
 }
 
 static dbus_bool_t
@@ -1130,6 +1150,10 @@
 
           dbus_free (context->pidfile);
 	}
+
+      if (context->initial_fd_limit)
+        _dbus_rlimit_free (context->initial_fd_limit);
+
       dbus_free (context);
 
       dbus_server_free_data_slot (&server_data_slot);
@@ -1294,6 +1318,12 @@
   return context->limits.reply_timeout;
 }
 
+DBusRLimit *
+bus_context_get_initial_fd_limit (BusContext *context)
+{
+  return context->initial_fd_limit;
+}
+
 void
 bus_context_log (BusContext *context, DBusSystemLogSeverity severity, const char *msg, ...) _DBUS_GNUC_PRINTF (3, 4);
 
diff -Nru dbus-1.8.8/bus/bus.h dbus-1.8.10/bus/bus.h
--- dbus-1.8.8/bus/bus.h	2014-09-15 12:29:28.000000000 +0100
+++ dbus-1.8.10/bus/bus.h	2014-11-04 15:04:06.000000000 +0000
@@ -116,6 +116,7 @@
 int               bus_context_get_max_match_rules_per_connection (BusContext       *context);
 int               bus_context_get_max_replies_per_connection     (BusContext       *context);
 int               bus_context_get_reply_timeout                  (BusContext       *context);
+DBusRLimit *      bus_context_get_initial_fd_limit               (BusContext       *context);
 void              bus_context_log                                (BusContext       *context,
                                                                   DBusSystemLogSeverity severity,
                                                                   const char       *msg,
diff -Nru dbus-1.8.8/configure dbus-1.8.10/configure
--- dbus-1.8.8/configure	2014-09-15 12:43:15.000000000 +0100
+++ dbus-1.8.10/configure	2014-11-06 15:40:18.000000000 +0000
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for dbus 1.8.8.
+# Generated by GNU Autoconf 2.69 for dbus 1.8.10.
 #
 # Report bugs to <https://bugs.freedesktop.org/enter_bug.cgi?product=dbus>.
 #
@@ -591,8 +591,8 @@
 # Identity of this package.
 PACKAGE_NAME='dbus'
 PACKAGE_TARNAME='dbus'
-PACKAGE_VERSION='1.8.8'
-PACKAGE_STRING='dbus 1.8.8'
+PACKAGE_VERSION='1.8.10'
+PACKAGE_STRING='dbus 1.8.10'
 PACKAGE_BUGREPORT='https://bugs.freedesktop.org/enter_bug.cgi?product=dbus'
 PACKAGE_URL=''
 
@@ -1513,7 +1513,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures dbus 1.8.8 to adapt to many kinds of systems.
+\`configure' configures dbus 1.8.10 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1587,7 +1587,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of dbus 1.8.8:";;
+     short | recursive ) echo "Configuration of dbus 1.8.10:";;
    esac
   cat <<\_ACEOF
 
@@ -1784,7 +1784,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-dbus configure 1.8.8
+dbus configure 1.8.10
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2503,7 +2503,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by dbus $as_me 1.8.8, which was
+It was created by dbus $as_me 1.8.10, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3132,8 +3132,8 @@
 ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
 program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
 
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 if test x"${MISSING+set}" != xset; then
   case $am_aux_dir in
@@ -3446,7 +3446,7 @@
 
 # Define the identity of the package.
  PACKAGE='dbus'
- VERSION='1.8.8'
+ VERSION='1.8.10'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3746,7 +3746,7 @@
 
 ## increment any time the source changes; set to
 ##  0 if you increment CURRENT
-LT_REVISION=7
+LT_REVISION=8
 
 ## increment if any interfaces have been added; set to 0
 ## if any interfaces have been changed or removed. removal has
@@ -3759,8 +3759,8 @@
 
 DBUS_MAJOR_VERSION=1
 DBUS_MINOR_VERSION=8
-DBUS_MICRO_VERSION=8
-DBUS_VERSION=1.8.8
+DBUS_MICRO_VERSION=10
+DBUS_VERSION=1.8.10
 
 
 
@@ -23428,7 +23428,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by dbus $as_me 1.8.8, which was
+This file was extended by dbus $as_me 1.8.10, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -23494,7 +23494,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-dbus config.status 1.8.8
+dbus config.status 1.8.10
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff -Nru dbus-1.8.8/configure.ac dbus-1.8.10/configure.ac
--- dbus-1.8.8/configure.ac	2014-09-15 12:42:50.000000000 +0100
+++ dbus-1.8.10/configure.ac	2014-11-06 15:34:45.000000000 +0000
@@ -3,7 +3,7 @@
 
 m4_define([dbus_major_version], [1])
 m4_define([dbus_minor_version], [8])
-m4_define([dbus_micro_version], [8])
+m4_define([dbus_micro_version], [10])
 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=7
+LT_REVISION=8
 
 ## increment if any interfaces have been added; set to 0
 ## if any interfaces have been changed or removed. removal has
diff -Nru dbus-1.8.8/dbus/dbus-sysdeps.h dbus-1.8.10/dbus/dbus-sysdeps.h
--- dbus-1.8.8/dbus/dbus-sysdeps.h	2014-09-15 12:27:24.000000000 +0100
+++ dbus-1.8.10/dbus/dbus-sysdeps.h	2014-11-06 15:30:51.000000000 +0000
@@ -546,8 +546,6 @@
 
 void _dbus_flush_caches (void);
 
-void _dbus_request_file_descriptor_limit (unsigned int limit);
-
 /*
  * replaces the term DBUS_PREFIX in configure_time_path by the
  * current dbus installation directory. On unix this function is a noop
@@ -566,6 +564,15 @@
  */
 #define DBUS_DEFAULT_MESSAGE_UNIX_FDS 16
 
+typedef struct DBusRLimit DBusRLimit;
+
+DBusRLimit     *_dbus_rlimit_save_fd_limit                 (DBusError    *error);
+dbus_bool_t     _dbus_rlimit_raise_fd_limit_if_privileged  (unsigned int  desired,
+                                                            DBusError    *error);
+dbus_bool_t     _dbus_rlimit_restore_fd_limit              (DBusRLimit   *saved,
+                                                            DBusError    *error);
+void            _dbus_rlimit_free                          (DBusRLimit   *lim);
+
 /** @} */
 
 DBUS_END_DECLS
diff -Nru dbus-1.8.8/dbus/dbus-sysdeps-util-unix.c dbus-1.8.10/dbus/dbus-sysdeps-util-unix.c
--- dbus-1.8.8/dbus/dbus-sysdeps-util-unix.c	2014-09-12 12:52:11.000000000 +0100
+++ dbus-1.8.10/dbus/dbus-sysdeps-util-unix.c	2014-11-06 15:30:51.000000000 +0000
@@ -378,53 +378,140 @@
 }
 #endif /* !HAVE_LIBAUDIT */
 
+#ifdef HAVE_SETRLIMIT
 
-/**
- * Attempt to ensure that the current process can open
- * at least @p limit file descriptors.
- *
- * If @p limit is lower than the current, it will not be
- * lowered.  No error is returned if the request can
- * not be satisfied.
- *
- * @param limit number of file descriptors
+/* We assume that if we have setrlimit, we also have getrlimit and
+ * struct rlimit.
  */
-void
-_dbus_request_file_descriptor_limit (unsigned int limit)
+
+struct DBusRLimit {
+    struct rlimit lim;
+};
+
+DBusRLimit *
+_dbus_rlimit_save_fd_limit (DBusError *error)
+{
+  DBusRLimit *self;
+
+  self = dbus_new0 (DBusRLimit, 1);
+
+  if (self == NULL)
+    {
+      _DBUS_SET_OOM (error);
+      return NULL;
+    }
+
+  if (getrlimit (RLIMIT_NOFILE, &self->lim) < 0)
+    {
+      dbus_set_error (error, _dbus_error_from_errno (errno),
+                      "Failed to get fd limit: %s", _dbus_strerror (errno));
+      dbus_free (self);
+      return NULL;
+    }
+
+  return self;
+}
+
+dbus_bool_t
+_dbus_rlimit_raise_fd_limit_if_privileged (unsigned int  desired,
+                                           DBusError    *error)
 {
-#ifdef HAVE_SETRLIMIT
   struct rlimit lim;
-  struct rlimit target_lim;
 
   /* No point to doing this practically speaking
    * if we're not uid 0.  We expect the system
    * bus to use this before we change UID, and
-   * the session bus takes the Linux default
-   * of 1024 for both cur and max.
+   * the session bus takes the Linux default,
+   * currently 1024 for cur and 4096 for max.
    */
   if (getuid () != 0)
-    return;
+    {
+      /* not an error, we're probably the session bus */
+      return TRUE;
+    }
 
   if (getrlimit (RLIMIT_NOFILE, &lim) < 0)
-    return;
-
-  if (lim.rlim_cur >= limit)
-    return;
+    {
+      dbus_set_error (error, _dbus_error_from_errno (errno),
+                      "Failed to get fd limit: %s", _dbus_strerror (errno));
+      return FALSE;
+    }
+
+  if (lim.rlim_cur == RLIM_INFINITY || lim.rlim_cur >= desired)
+    {
+      /* not an error, everything is fine */
+      return TRUE;
+    }
 
   /* Ignore "maximum limit", assume we have the "superuser"
    * privileges.  On Linux this is CAP_SYS_RESOURCE.
    */
-  target_lim.rlim_cur = target_lim.rlim_max = limit;
-  /* Also ignore errors; if we fail, we will at least work
-   * up to whatever limit we had, which seems better than
-   * just outright aborting.
-   *
-   * However, in the future we should probably log this so OS builders
-   * have a chance to notice any misconfiguration like dbus-daemon
-   * being started without CAP_SYS_RESOURCE.
-   */
-  setrlimit (RLIMIT_NOFILE, &target_lim);
+  lim.rlim_cur = lim.rlim_max = desired;
+
+  if (setrlimit (RLIMIT_NOFILE, &lim) < 0)
+    {
+      dbus_set_error (error, _dbus_error_from_errno (errno),
+                      "Failed to set fd limit to %u: %s",
+                      desired, _dbus_strerror (errno));
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+dbus_bool_t
+_dbus_rlimit_restore_fd_limit (DBusRLimit *saved,
+                               DBusError  *error)
+{
+  if (setrlimit (RLIMIT_NOFILE, &saved->lim) < 0)
+    {
+      dbus_set_error (error, _dbus_error_from_errno (errno),
+                      "Failed to restore old fd limit: %s",
+                      _dbus_strerror (errno));
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+#else /* !HAVE_SETRLIMIT */
+
+static void
+fd_limit_not_supported (DBusError *error)
+{
+  dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
+                  "cannot change fd limit on this platform");
+}
+
+DBusRLimit *
+_dbus_rlimit_save_fd_limit (DBusError *error)
+{
+  fd_limit_not_supported (error);
+  return NULL;
+}
+
+dbus_bool_t
+_dbus_rlimit_raise_fd_limit_if_privileged (unsigned int  desired,
+                                           DBusError    *error)
+{
+  fd_limit_not_supported (error);
+  return FALSE;
+}
+
+dbus_bool_t
+_dbus_rlimit_restore_fd_limit (DBusRLimit *saved,
+                               DBusError  *error)
+{
+  fd_limit_not_supported (error);
+  return FALSE;
+}
+
 #endif
+
+void
+_dbus_rlimit_free (DBusRLimit *lim)
+{
+  dbus_free (lim);
 }
 
 void
diff -Nru dbus-1.8.8/dbus/dbus-sysdeps-util-win.c dbus-1.8.10/dbus/dbus-sysdeps-util-win.c
--- dbus-1.8.8/dbus/dbus-sysdeps-util-win.c	2014-09-12 12:52:11.000000000 +0100
+++ dbus-1.8.10/dbus/dbus-sysdeps-util-win.c	2014-11-06 15:30:51.000000000 +0000
@@ -258,9 +258,42 @@
   return TRUE;
 }
 
+static void
+fd_limit_not_supported (DBusError *error)
+{
+  dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
+                  "cannot change fd limit on this platform");
+}
+
+DBusRLimit *
+_dbus_rlimit_save_fd_limit (DBusError *error)
+{
+  fd_limit_not_supported (error);
+  return NULL;
+}
+
+dbus_bool_t
+_dbus_rlimit_raise_fd_limit_if_privileged (unsigned int  desired,
+                                           DBusError    *error)
+{
+  fd_limit_not_supported (error);
+  return FALSE;
+}
+
+dbus_bool_t
+_dbus_rlimit_restore_fd_limit (DBusRLimit *saved,
+                               DBusError  *error)
+{
+  fd_limit_not_supported (error);
+  return FALSE;
+}
+
 void
-_dbus_request_file_descriptor_limit (unsigned int limit)
+_dbus_rlimit_free (DBusRLimit *lim)
 {
+  /* _dbus_rlimit_save_fd_limit() cannot return non-NULL on Windows
+   * so there cannot be anything to free */
+  _dbus_assert (lim == NULL);
 }
 
 void
diff -Nru dbus-1.8.8/debian/changelog dbus-1.8.10/debian/changelog
--- dbus-1.8.8/debian/changelog	2014-10-06 19:17:12.000000000 +0100
+++ dbus-1.8.10/debian/changelog	2014-11-06 16:28:35.000000000 +0000
@@ -1,3 +1,15 @@
+dbus (1.8.10-1) unstable; urgency=medium
+
+  * New upstream release 1.8.10
+    - raise dbus-daemon's file descriptor limit to 65536 to avoid an
+      opportunity for denial of service
+      (CVE-2014-7824, an incomplete fix for CVE-2014-3636)
+  * Start 'dbus-daemon --system' as root under sysvinit (it already
+    starts as root under systemd), so it can increase its file
+    descriptor limit
+
+ -- Simon McVittie <smcv@debian.org>  Thu, 06 Nov 2014 16:28:22 +0000
+
 dbus (1.8.8-2) unstable; urgency=medium
 
   [ Michael Biebl ]
diff -Nru dbus-1.8.8/debian/dbus.init dbus-1.8.10/debian/dbus.init
--- dbus-1.8.8/debian/dbus.init	2014-10-06 19:17:12.000000000 +0100
+++ dbus-1.8.10/debian/dbus.init	2014-11-06 16:28:35.000000000 +0000
@@ -69,7 +69,7 @@
 
   log_daemon_msg "Starting $DESC" "$NAME"
   start-stop-daemon --start --quiet --pidfile $PIDFILE \
-    --user $DAEMONUSER --exec $DAEMON -- --system $PARAMS
+    --exec $DAEMON -- --system $PARAMS
   log_end_msg $?
 }
 
diff -Nru dbus-1.8.8/doc/Makefile.in dbus-1.8.10/doc/Makefile.in
--- dbus-1.8.8/doc/Makefile.in	2014-09-15 12:43:15.000000000 +0100
+++ dbus-1.8.10/doc/Makefile.in	2014-11-06 15:40:19.000000000 +0000
@@ -666,8 +666,8 @@
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
-@DBUS_DOXYGEN_DOCS_ENABLED_FALSE@install-data-local:
 @DBUS_DOXYGEN_DOCS_ENABLED_FALSE@uninstall-local:
+@DBUS_DOXYGEN_DOCS_ENABLED_FALSE@install-data-local:
 clean: clean-am
 
 clean-am: clean-generic clean-libtool clean-local mostlyclean-am
diff -Nru dbus-1.8.8/NEWS dbus-1.8.10/NEWS
--- dbus-1.8.8/NEWS	2014-09-15 12:42:33.000000000 +0100
+++ dbus-1.8.10/NEWS	2014-11-06 15:39:02.000000000 +0000
@@ -1,3 +1,15 @@
+D-Bus 1.8.10 (2014-11-10)
+==
+
+The “tenants with a leaking roof get priority” release.
+
+Security fixes:
+
+• Increase dbus-daemon's RLIMIT_NOFILE rlimit to 65536
+  so that CVE-2014-3636 part A cannot exhaust the system bus'
+  file descriptors, completing the incomplete fix in 1.8.8.
+  (CVE-2014-7824, fd.o #85105; Simon McVittie, Alban Crequy)
+
 D-Bus 1.8.8 (2014-09-16)
 ==
 
diffstat for dbus-1.8.8 dbus-1.8.10

 NEWS                          |   12 +++
 bus/activation.c              |   28 +++++++-
 bus/bus.c                     |   50 +++++++++++---
 bus/bus.h                     |    1 
 configure.ac                  |    4 -
 dbus/dbus-sysdeps-util-unix.c |  147 +++++++++++++++++++++++++++++++++---------
 dbus/dbus-sysdeps-util-win.c  |   35 +++++++++-
 dbus/dbus-sysdeps.h           |   11 ++-
 debian/changelog              |   12 +++
 debian/dbus.init              |    2 
 10 files changed, 255 insertions(+), 47 deletions(-)

diff -Nru --exclude aclocal.m4 --exclude configure --exclude Makefile.in dbus-1.8.8/bus/activation.c dbus-1.8.10/bus/activation.c
--- dbus-1.8.8/bus/activation.c	2014-09-12 12:52:11.000000000 +0100
+++ dbus-1.8.10/bus/activation.c	2014-11-06 15:30:51.000000000 +0000
@@ -1688,6 +1688,31 @@
   return retval;
 }
 
+static void
+child_setup (void *user_data)
+{
+#ifdef DBUS_UNIX
+  BusActivation *activation = user_data;
+  DBusRLimit *initial_fd_limit;
+  DBusError error;
+
+  dbus_error_init (&error);
+  initial_fd_limit = bus_context_get_initial_fd_limit (activation->context);
+
+  if (initial_fd_limit != NULL &&
+      !_dbus_rlimit_restore_fd_limit (initial_fd_limit, &error))
+    {
+      /* unfortunately we don't actually know the service name here */
+      bus_context_log (activation->context,
+                       DBUS_SYSTEM_LOG_INFO,
+                       "Failed to reset fd limit before activating "
+                       "service: %s: %s",
+                       error.name, error.message);
+    }
+#endif
+}
+
+
 dbus_bool_t
 bus_activation_activate_service (BusActivation  *activation,
                                  DBusConnection *connection,
@@ -2121,7 +2146,8 @@
                                           service_name,
                                           argv,
                                           envp,
-                                          NULL, activation,
+                                          child_setup,
+                                          activation,
                                           &tmp_error))
     {
       _dbus_verbose ("Failed to spawn child\n");
diff -Nru --exclude aclocal.m4 --exclude configure --exclude Makefile.in dbus-1.8.8/bus/bus.c dbus-1.8.10/bus/bus.c
--- dbus-1.8.8/bus/bus.c	2014-09-15 12:29:28.000000000 +0100
+++ dbus-1.8.10/bus/bus.c	2014-11-06 15:30:51.000000000 +0000
@@ -64,6 +64,7 @@
   BusPolicy *policy;
   BusMatchmaker *matchmaker;
   BusLimits limits;
+  DBusRLimit *initial_fd_limit;
   unsigned int fork : 1;
   unsigned int syslog : 1;
   unsigned int keep_umask : 1;
@@ -659,19 +660,38 @@
 static void
 raise_file_descriptor_limit (BusContext      *context)
 {
+#ifdef DBUS_UNIX
+  DBusError error = DBUS_ERROR_INIT;
 
-  /* I just picked this out of thin air; we need some extra
-   * descriptors for things like any internal pipes we create,
-   * inotify, connections to SELinux, etc.
-   */
-  unsigned int arbitrary_extra_fds = 32;
-  unsigned int limit;
+  /* we only do this once */
+  if (context->initial_fd_limit != NULL)
+    return;
 
-  limit = context->limits.max_completed_connections +
-    context->limits.max_incomplete_connections
-    + arbitrary_extra_fds;
+  context->initial_fd_limit = _dbus_rlimit_save_fd_limit (&error);
 
-  _dbus_request_file_descriptor_limit (limit);
+  if (context->initial_fd_limit == NULL)
+    {
+      bus_context_log (context, DBUS_SYSTEM_LOG_INFO,
+                       "%s: %s", error.name, error.message);
+      dbus_error_free (&error);
+      return;
+    }
+
+  /* We used to compute a suitable rlimit based on the configured number
+   * of connections, but that breaks down as soon as we allow fd-passing,
+   * because each connection is allowed to pass 64 fds to us, and if
+   * they all did, we'd hit kernel limits. We now hard-code 64k as a
+   * good limit, like systemd does: that's enough to avoid DoS from
+   * anything short of multiple uids conspiring against us.
+   */
+  if (!_dbus_rlimit_raise_fd_limit_if_privileged (65536, &error))
+    {
+      bus_context_log (context, DBUS_SYSTEM_LOG_INFO,
+                       "%s: %s", error.name, error.message);
+      dbus_error_free (&error);
+      return;
+    }
+#endif
 }
 
 static dbus_bool_t
@@ -1130,6 +1150,10 @@
 
           dbus_free (context->pidfile);
 	}
+
+      if (context->initial_fd_limit)
+        _dbus_rlimit_free (context->initial_fd_limit);
+
       dbus_free (context);
 
       dbus_server_free_data_slot (&server_data_slot);
@@ -1294,6 +1318,12 @@
   return context->limits.reply_timeout;
 }
 
+DBusRLimit *
+bus_context_get_initial_fd_limit (BusContext *context)
+{
+  return context->initial_fd_limit;
+}
+
 void
 bus_context_log (BusContext *context, DBusSystemLogSeverity severity, const char *msg, ...) _DBUS_GNUC_PRINTF (3, 4);
 
diff -Nru --exclude aclocal.m4 --exclude configure --exclude Makefile.in dbus-1.8.8/bus/bus.h dbus-1.8.10/bus/bus.h
--- dbus-1.8.8/bus/bus.h	2014-09-15 12:29:28.000000000 +0100
+++ dbus-1.8.10/bus/bus.h	2014-11-04 15:04:06.000000000 +0000
@@ -116,6 +116,7 @@
 int               bus_context_get_max_match_rules_per_connection (BusContext       *context);
 int               bus_context_get_max_replies_per_connection     (BusContext       *context);
 int               bus_context_get_reply_timeout                  (BusContext       *context);
+DBusRLimit *      bus_context_get_initial_fd_limit               (BusContext       *context);
 void              bus_context_log                                (BusContext       *context,
                                                                   DBusSystemLogSeverity severity,
                                                                   const char       *msg,
diff -Nru --exclude aclocal.m4 --exclude configure --exclude Makefile.in dbus-1.8.8/configure.ac dbus-1.8.10/configure.ac
--- dbus-1.8.8/configure.ac	2014-09-15 12:42:50.000000000 +0100
+++ dbus-1.8.10/configure.ac	2014-11-06 15:34:45.000000000 +0000
@@ -3,7 +3,7 @@
 
 m4_define([dbus_major_version], [1])
 m4_define([dbus_minor_version], [8])
-m4_define([dbus_micro_version], [8])
+m4_define([dbus_micro_version], [10])
 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=7
+LT_REVISION=8
 
 ## increment if any interfaces have been added; set to 0
 ## if any interfaces have been changed or removed. removal has
diff -Nru --exclude aclocal.m4 --exclude configure --exclude Makefile.in dbus-1.8.8/dbus/dbus-sysdeps.h dbus-1.8.10/dbus/dbus-sysdeps.h
--- dbus-1.8.8/dbus/dbus-sysdeps.h	2014-09-15 12:27:24.000000000 +0100
+++ dbus-1.8.10/dbus/dbus-sysdeps.h	2014-11-06 15:30:51.000000000 +0000
@@ -546,8 +546,6 @@
 
 void _dbus_flush_caches (void);
 
-void _dbus_request_file_descriptor_limit (unsigned int limit);
-
 /*
  * replaces the term DBUS_PREFIX in configure_time_path by the
  * current dbus installation directory. On unix this function is a noop
@@ -566,6 +564,15 @@
  */
 #define DBUS_DEFAULT_MESSAGE_UNIX_FDS 16
 
+typedef struct DBusRLimit DBusRLimit;
+
+DBusRLimit     *_dbus_rlimit_save_fd_limit                 (DBusError    *error);
+dbus_bool_t     _dbus_rlimit_raise_fd_limit_if_privileged  (unsigned int  desired,
+                                                            DBusError    *error);
+dbus_bool_t     _dbus_rlimit_restore_fd_limit              (DBusRLimit   *saved,
+                                                            DBusError    *error);
+void            _dbus_rlimit_free                          (DBusRLimit   *lim);
+
 /** @} */
 
 DBUS_END_DECLS
diff -Nru --exclude aclocal.m4 --exclude configure --exclude Makefile.in dbus-1.8.8/dbus/dbus-sysdeps-util-unix.c dbus-1.8.10/dbus/dbus-sysdeps-util-unix.c
--- dbus-1.8.8/dbus/dbus-sysdeps-util-unix.c	2014-09-12 12:52:11.000000000 +0100
+++ dbus-1.8.10/dbus/dbus-sysdeps-util-unix.c	2014-11-06 15:30:51.000000000 +0000
@@ -378,53 +378,140 @@
 }
 #endif /* !HAVE_LIBAUDIT */
 
+#ifdef HAVE_SETRLIMIT
 
-/**
- * Attempt to ensure that the current process can open
- * at least @p limit file descriptors.
- *
- * If @p limit is lower than the current, it will not be
- * lowered.  No error is returned if the request can
- * not be satisfied.
- *
- * @param limit number of file descriptors
+/* We assume that if we have setrlimit, we also have getrlimit and
+ * struct rlimit.
  */
-void
-_dbus_request_file_descriptor_limit (unsigned int limit)
+
+struct DBusRLimit {
+    struct rlimit lim;
+};
+
+DBusRLimit *
+_dbus_rlimit_save_fd_limit (DBusError *error)
+{
+  DBusRLimit *self;
+
+  self = dbus_new0 (DBusRLimit, 1);
+
+  if (self == NULL)
+    {
+      _DBUS_SET_OOM (error);
+      return NULL;
+    }
+
+  if (getrlimit (RLIMIT_NOFILE, &self->lim) < 0)
+    {
+      dbus_set_error (error, _dbus_error_from_errno (errno),
+                      "Failed to get fd limit: %s", _dbus_strerror (errno));
+      dbus_free (self);
+      return NULL;
+    }
+
+  return self;
+}
+
+dbus_bool_t
+_dbus_rlimit_raise_fd_limit_if_privileged (unsigned int  desired,
+                                           DBusError    *error)
 {
-#ifdef HAVE_SETRLIMIT
   struct rlimit lim;
-  struct rlimit target_lim;
 
   /* No point to doing this practically speaking
    * if we're not uid 0.  We expect the system
    * bus to use this before we change UID, and
-   * the session bus takes the Linux default
-   * of 1024 for both cur and max.
+   * the session bus takes the Linux default,
+   * currently 1024 for cur and 4096 for max.
    */
   if (getuid () != 0)
-    return;
+    {
+      /* not an error, we're probably the session bus */
+      return TRUE;
+    }
 
   if (getrlimit (RLIMIT_NOFILE, &lim) < 0)
-    return;
-
-  if (lim.rlim_cur >= limit)
-    return;
+    {
+      dbus_set_error (error, _dbus_error_from_errno (errno),
+                      "Failed to get fd limit: %s", _dbus_strerror (errno));
+      return FALSE;
+    }
+
+  if (lim.rlim_cur == RLIM_INFINITY || lim.rlim_cur >= desired)
+    {
+      /* not an error, everything is fine */
+      return TRUE;
+    }
 
   /* Ignore "maximum limit", assume we have the "superuser"
    * privileges.  On Linux this is CAP_SYS_RESOURCE.
    */
-  target_lim.rlim_cur = target_lim.rlim_max = limit;
-  /* Also ignore errors; if we fail, we will at least work
-   * up to whatever limit we had, which seems better than
-   * just outright aborting.
-   *
-   * However, in the future we should probably log this so OS builders
-   * have a chance to notice any misconfiguration like dbus-daemon
-   * being started without CAP_SYS_RESOURCE.
-   */
-  setrlimit (RLIMIT_NOFILE, &target_lim);
+  lim.rlim_cur = lim.rlim_max = desired;
+
+  if (setrlimit (RLIMIT_NOFILE, &lim) < 0)
+    {
+      dbus_set_error (error, _dbus_error_from_errno (errno),
+                      "Failed to set fd limit to %u: %s",
+                      desired, _dbus_strerror (errno));
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+dbus_bool_t
+_dbus_rlimit_restore_fd_limit (DBusRLimit *saved,
+                               DBusError  *error)
+{
+  if (setrlimit (RLIMIT_NOFILE, &saved->lim) < 0)
+    {
+      dbus_set_error (error, _dbus_error_from_errno (errno),
+                      "Failed to restore old fd limit: %s",
+                      _dbus_strerror (errno));
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+#else /* !HAVE_SETRLIMIT */
+
+static void
+fd_limit_not_supported (DBusError *error)
+{
+  dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
+                  "cannot change fd limit on this platform");
+}
+
+DBusRLimit *
+_dbus_rlimit_save_fd_limit (DBusError *error)
+{
+  fd_limit_not_supported (error);
+  return NULL;
+}
+
+dbus_bool_t
+_dbus_rlimit_raise_fd_limit_if_privileged (unsigned int  desired,
+                                           DBusError    *error)
+{
+  fd_limit_not_supported (error);
+  return FALSE;
+}
+
+dbus_bool_t
+_dbus_rlimit_restore_fd_limit (DBusRLimit *saved,
+                               DBusError  *error)
+{
+  fd_limit_not_supported (error);
+  return FALSE;
+}
+
 #endif
+
+void
+_dbus_rlimit_free (DBusRLimit *lim)
+{
+  dbus_free (lim);
 }
 
 void
diff -Nru --exclude aclocal.m4 --exclude configure --exclude Makefile.in dbus-1.8.8/dbus/dbus-sysdeps-util-win.c dbus-1.8.10/dbus/dbus-sysdeps-util-win.c
--- dbus-1.8.8/dbus/dbus-sysdeps-util-win.c	2014-09-12 12:52:11.000000000 +0100
+++ dbus-1.8.10/dbus/dbus-sysdeps-util-win.c	2014-11-06 15:30:51.000000000 +0000
@@ -258,9 +258,42 @@
   return TRUE;
 }
 
+static void
+fd_limit_not_supported (DBusError *error)
+{
+  dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
+                  "cannot change fd limit on this platform");
+}
+
+DBusRLimit *
+_dbus_rlimit_save_fd_limit (DBusError *error)
+{
+  fd_limit_not_supported (error);
+  return NULL;
+}
+
+dbus_bool_t
+_dbus_rlimit_raise_fd_limit_if_privileged (unsigned int  desired,
+                                           DBusError    *error)
+{
+  fd_limit_not_supported (error);
+  return FALSE;
+}
+
+dbus_bool_t
+_dbus_rlimit_restore_fd_limit (DBusRLimit *saved,
+                               DBusError  *error)
+{
+  fd_limit_not_supported (error);
+  return FALSE;
+}
+
 void
-_dbus_request_file_descriptor_limit (unsigned int limit)
+_dbus_rlimit_free (DBusRLimit *lim)
 {
+  /* _dbus_rlimit_save_fd_limit() cannot return non-NULL on Windows
+   * so there cannot be anything to free */
+  _dbus_assert (lim == NULL);
 }
 
 void
diff -Nru --exclude aclocal.m4 --exclude configure --exclude Makefile.in dbus-1.8.8/debian/changelog dbus-1.8.10/debian/changelog
--- dbus-1.8.8/debian/changelog	2014-10-06 19:17:12.000000000 +0100
+++ dbus-1.8.10/debian/changelog	2014-11-06 16:28:35.000000000 +0000
@@ -1,3 +1,15 @@
+dbus (1.8.10-1) unstable; urgency=medium
+
+  * New upstream release 1.8.10
+    - raise dbus-daemon's file descriptor limit to 65536 to avoid an
+      opportunity for denial of service
+      (CVE-2014-7824, an incomplete fix for CVE-2014-3636)
+  * Start 'dbus-daemon --system' as root under sysvinit (it already
+    starts as root under systemd), so it can increase its file
+    descriptor limit
+
+ -- Simon McVittie <smcv@debian.org>  Thu, 06 Nov 2014 16:28:22 +0000
+
 dbus (1.8.8-2) unstable; urgency=medium
 
   [ Michael Biebl ]
diff -Nru --exclude aclocal.m4 --exclude configure --exclude Makefile.in dbus-1.8.8/debian/dbus.init dbus-1.8.10/debian/dbus.init
--- dbus-1.8.8/debian/dbus.init	2014-10-06 19:17:12.000000000 +0100
+++ dbus-1.8.10/debian/dbus.init	2014-11-06 16:28:35.000000000 +0000
@@ -69,7 +69,7 @@
 
   log_daemon_msg "Starting $DESC" "$NAME"
   start-stop-daemon --start --quiet --pidfile $PIDFILE \
-    --user $DAEMONUSER --exec $DAEMON -- --system $PARAMS
+    --exec $DAEMON -- --system $PARAMS
   log_end_msg $?
 }
 
diff -Nru --exclude aclocal.m4 --exclude configure --exclude Makefile.in dbus-1.8.8/NEWS dbus-1.8.10/NEWS
--- dbus-1.8.8/NEWS	2014-09-15 12:42:33.000000000 +0100
+++ dbus-1.8.10/NEWS	2014-11-06 15:39:02.000000000 +0000
@@ -1,3 +1,15 @@
+D-Bus 1.8.10 (2014-11-10)
+==
+
+The “tenants with a leaking roof get priority” release.
+
+Security fixes:
+
+• Increase dbus-daemon's RLIMIT_NOFILE rlimit to 65536
+  so that CVE-2014-3636 part A cannot exhaust the system bus'
+  file descriptors, completing the incomplete fix in 1.8.8.
+  (CVE-2014-7824, fd.o #85105; Simon McVittie, Alban Crequy)
+
 D-Bus 1.8.8 (2014-09-16)
 ==
 

--- End Message ---
--- Begin Message ---
On Wed, Nov 12, 2014 at 00:12:45 +0100, Cyril Brulebois wrote:

> Checking older build logs, I don't see any match for dbus-udeb or its
> library udeb, so no objection.
> 
added unblock-udeb.

Cheers,
Julien

Attachment: signature.asc
Description: Digital signature


--- End Message ---

Reply to: