summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <smcv@debian.org>2015-01-02 11:11:58 +0000
committerSimon McVittie <smcv@debian.org>2015-01-02 11:11:58 +0000
commit226e9039099f3c04e9bbf474a3b145a681ac4a2f (patch)
tree1f67656e0f4239739bc1c60dbf4daf52a9b1995e
parent4ad8b86eff14185ac6c005343261387f058c89e7 (diff)
downloaddbus-226e9039099f3c04e9bbf474a3b145a681ac4a2f.tar.gz
Imported Upstream version 1.9.6upstream/1.9.6
-rw-r--r--NEWS31
-rw-r--r--bus/driver.c70
-rw-r--r--bus/driver.h4
-rw-r--r--bus/stats.c7
-rwxr-xr-xconfigure26
-rw-r--r--configure.ac4
-rw-r--r--dbus/dbus-sysdeps-win.c2
-rw-r--r--doc/dbus-specification.xml10
-rw-r--r--test/dbus-daemon.c87
9 files changed, 222 insertions, 19 deletions
diff --git a/NEWS b/NEWS
index c647ba21..3ed89667 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,34 @@
+D-Bus 1.9.6 (2015-01-05)
+==
+
+The “I do have a bread knife” release.
+
+Security hardening:
+
+• Do not allow calls to UpdateActivationEnvironment from uids other than
+ the uid of the dbus-daemon. If a system service installs unsafe
+ security policy rules that allow arbitrary method calls
+ (such as CVE-2014-8148) then this prevents memory consumption and
+ possible privilege escalation via UpdateActivationEnvironment.
+
+ We believe that in practice, privilege escalation here is avoided
+ by dbus-daemon-launch-helper sanitizing its environment; but
+ it seems better to be safe.
+
+• Do not allow calls to UpdateActivationEnvironment or the Stats interface
+ on object paths other than /org/freedesktop/DBus. Some system services
+ install unsafe security policy rules that allow arbitrary method calls
+ to any destination, method and interface with a specified object path;
+ while less bad than allowing arbitrary method calls, these security
+ policies are still harmful, since dbus-daemon normally offers the
+ same API on all object paths and other system services might behave
+ similarly.
+
+Other fixes:
+
+• Add missing initialization so GetExtendedTcpTable doesn't crash on
+ Windows Vista SP0 (fd.o #77008, Илья А. Ткаченко)
+
D-Bus 1.9.4 (2014-11-24)
==
diff --git a/bus/driver.c b/bus/driver.c
index 777b2f89..952061c6 100644
--- a/bus/driver.c
+++ b/bus/driver.c
@@ -878,6 +878,44 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ if (!bus_driver_check_message_is_for_us (message, error))
+ return FALSE;
+
+#ifdef DBUS_UNIX
+ {
+ /* UpdateActivationEnvironment is basically a recipe for privilege
+ * escalation so let's be extra-careful: do not allow the sysadmin
+ * to shoot themselves in the foot. */
+ unsigned long uid;
+
+ if (!dbus_connection_get_unix_user (connection, &uid))
+ {
+ bus_context_log (bus_transaction_get_context (transaction),
+ DBUS_SYSTEM_LOG_SECURITY,
+ "rejected attempt to call UpdateActivationEnvironment by "
+ "unknown uid");
+ dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
+ "rejected attempt to call UpdateActivationEnvironment by "
+ "unknown uid");
+ return FALSE;
+ }
+
+ /* On the system bus, we could in principle allow uid 0 to call
+ * UpdateActivationEnvironment; but they should know better anyway,
+ * and our default system.conf has always forbidden it */
+ if (!_dbus_unix_user_is_process_owner (uid))
+ {
+ bus_context_log (bus_transaction_get_context (transaction),
+ DBUS_SYSTEM_LOG_SECURITY,
+ "rejected attempt to call UpdateActivationEnvironment by uid %lu",
+ uid);
+ dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
+ "rejected attempt to call UpdateActivationEnvironment");
+ return FALSE;
+ }
+ }
+#endif
+
activation = bus_connection_get_activation (connection);
dbus_message_iter_init (message, &iter);
@@ -1966,6 +2004,38 @@ bus_driver_handle_introspect (DBusConnection *connection,
return FALSE;
}
+/*
+ * Set @error and return FALSE if the message is not directed to the
+ * dbus-daemon by its canonical object path. This is hardening against
+ * system services with poorly-written security policy files, which
+ * might allow sending dangerously broad equivalence classes of messages
+ * such as "anything with this assumed-to-be-safe object path".
+ *
+ * dbus-daemon is unusual in that it normally ignores the object path
+ * of incoming messages; we need to keep that behaviour for the "read"
+ * read-only method calls like GetConnectionUnixUser for backwards
+ * compatibility, but it seems safer to be more restrictive for things
+ * intended to be root-only or privileged-developers-only.
+ *
+ * It is possible that there are other system services with the same
+ * quirk as dbus-daemon.
+ */
+dbus_bool_t
+bus_driver_check_message_is_for_us (DBusMessage *message,
+ DBusError *error)
+{
+ if (!dbus_message_has_path (message, DBUS_PATH_DBUS))
+ {
+ dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
+ "Method '%s' is only available at the canonical object path '%s'",
+ dbus_message_get_member (message), DBUS_PATH_DBUS);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
dbus_bool_t
bus_driver_handle_message (DBusConnection *connection,
BusTransaction *transaction,
diff --git a/bus/driver.h b/bus/driver.h
index 713b2764..201709c4 100644
--- a/bus/driver.h
+++ b/bus/driver.h
@@ -46,7 +46,7 @@ dbus_bool_t bus_driver_send_service_owner_changed (const char *service_name
BusTransaction *transaction,
DBusError *error);
dbus_bool_t bus_driver_generate_introspect_string (DBusString *xml);
-
-
+dbus_bool_t bus_driver_check_message_is_for_us (DBusMessage *message,
+ DBusError *error);
#endif /* BUS_DRIVER_H */
diff --git a/bus/stats.c b/bus/stats.c
index 859c6a52..dace0e29 100644
--- a/bus/stats.c
+++ b/bus/stats.c
@@ -29,6 +29,7 @@
#include <dbus/dbus-connection-internal.h>
#include "connection.h"
+#include "driver.h"
#include "services.h"
#include "signals.h"
#include "utils.h"
@@ -50,6 +51,9 @@ bus_stats_handle_get_stats (DBusConnection *connection,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ if (!bus_driver_check_message_is_for_us (message, error))
+ return FALSE;
+
context = bus_transaction_get_context (transaction);
connections = bus_context_get_connections (context);
@@ -132,6 +136,9 @@ bus_stats_handle_get_connection_stats (DBusConnection *caller_connection,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ if (!bus_driver_check_message_is_for_us (message, error))
+ return FALSE;
+
registry = bus_connection_get_registry (caller_connection);
if (! dbus_message_get_args (message, error,
diff --git a/configure b/configure
index eee762a2..a74f65e6 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for dbus 1.9.4.
+# Generated by GNU Autoconf 2.69 for dbus 1.9.6.
#
# Report bugs to <https://bugs.freedesktop.org/enter_bug.cgi?product=dbus>.
#
@@ -591,8 +591,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='dbus'
PACKAGE_TARNAME='dbus'
-PACKAGE_VERSION='1.9.4'
-PACKAGE_STRING='dbus 1.9.4'
+PACKAGE_VERSION='1.9.6'
+PACKAGE_STRING='dbus 1.9.6'
PACKAGE_BUGREPORT='https://bugs.freedesktop.org/enter_bug.cgi?product=dbus'
PACKAGE_URL=''
@@ -1514,7 +1514,7 @@ if test "$ac_init_help" = "long"; then
# 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.9.4 to adapt to many kinds of systems.
+\`configure' configures dbus 1.9.6 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1588,7 +1588,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of dbus 1.9.4:";;
+ short | recursive ) echo "Configuration of dbus 1.9.6:";;
esac
cat <<\_ACEOF
@@ -1785,7 +1785,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-dbus configure 1.9.4
+dbus configure 1.9.6
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2561,7 +2561,7 @@ cat >config.log <<_ACEOF
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.9.4, which was
+It was created by dbus $as_me 1.9.6, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3504,7 +3504,7 @@ fi
# Define the identity of the package.
PACKAGE='dbus'
- VERSION='1.9.4'
+ VERSION='1.9.6'
cat >>confdefs.h <<_ACEOF
@@ -3804,7 +3804,7 @@ LT_CURRENT=13
## increment any time the source changes; set to
## 0 if you increment CURRENT
-LT_REVISION=1
+LT_REVISION=2
## increment if any interfaces have been added; set to 0
## if any interfaces have been changed or removed. removal has
@@ -3817,8 +3817,8 @@ LT_AGE=10
DBUS_MAJOR_VERSION=1
DBUS_MINOR_VERSION=9
-DBUS_MICRO_VERSION=4
-DBUS_VERSION=1.9.4
+DBUS_MICRO_VERSION=6
+DBUS_VERSION=1.9.6
@@ -23545,7 +23545,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# 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.9.4, which was
+This file was extended by dbus $as_me 1.9.6, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -23611,7 +23611,7 @@ _ACEOF
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.9.4
+dbus config.status 1.9.6
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 52255c7d..6dcb2818 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], [9])
-m4_define([dbus_micro_version], [4])
+m4_define([dbus_micro_version], [6])
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 @@ LT_CURRENT=13
## increment any time the source changes; set to
## 0 if you increment CURRENT
-LT_REVISION=1
+LT_REVISION=2
## 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-sysdeps-win.c b/dbus/dbus-sysdeps-win.c
index 2c18f40e..208e8522 100644
--- a/dbus/dbus-sysdeps-win.c
+++ b/dbus/dbus-sysdeps-win.c
@@ -146,7 +146,7 @@ static dbus_pid_t
get_pid_from_extended_tcp_table(int peer_port)
{
dbus_pid_t result;
- DWORD errorCode, size, i;
+ DWORD errorCode, size = 0, i;
MIB_TCPTABLE_OWNER_PID *tcp_table;
if ((errorCode =
diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml
index 6316bd83..1d23fa04 100644
--- a/doc/dbus-specification.xml
+++ b/doc/dbus-specification.xml
@@ -7,7 +7,7 @@
<articleinfo>
<title>D-Bus Specification</title>
<releaseinfo>Version 0.25</releaseinfo>
- <date>2014-11-10</date>
+ <date>(not yet released)</date>
<authorgroup>
<author>
<firstname>Havoc</firstname>
@@ -71,6 +71,14 @@
</authorgroup>
<revhistory>
<revision>
+ <revnumber>0.26</revnumber>
+ <date>(not yet released)</date>
+ <authorinitials>n/a</authorinitials>
+ <revremark>
+ see <ulink url='http://cgit.freedesktop.org/dbus/dbus/log/doc/dbus-specification.xml'>commit log</ulink>
+ </revremark>
+ </revision>
+ <revision>
<revnumber>0.25</revnumber>
<date>2014-11-10</date>
<authorinitials>smcv, lennart</authorinitials>
diff --git a/test/dbus-daemon.c b/test/dbus-daemon.c
index bb1d1374..1cd51d20 100644
--- a/test/dbus-daemon.c
+++ b/test/dbus-daemon.c
@@ -635,6 +635,91 @@ test_processid (Fixture *f,
}
static void
+test_canonical_path_uae (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "UpdateActivationEnvironment");
+ DBusPendingCall *pc;
+ DBusMessageIter args_iter;
+ DBusMessageIter arr_iter;
+
+ if (m == NULL)
+ g_error ("OOM");
+
+ dbus_message_iter_init_append (m, &args_iter);
+
+ /* Append an empty a{ss} (string => string dictionary). */
+ if (!dbus_message_iter_open_container (&args_iter, DBUS_TYPE_ARRAY,
+ "{ss}", &arr_iter) ||
+ !dbus_message_iter_close_container (&args_iter, &arr_iter))
+ g_error ("OOM");
+
+ if (!dbus_connection_send_with_reply (f->left_conn, m, &pc,
+ DBUS_TIMEOUT_USE_DEFAULT) ||
+ pc == NULL)
+ g_error ("OOM");
+
+ dbus_message_unref (m);
+ m = NULL;
+
+ if (dbus_pending_call_get_completed (pc))
+ pending_call_store_reply (pc, &m);
+ else if (!dbus_pending_call_set_notify (pc, pending_call_store_reply,
+ &m, NULL))
+ g_error ("OOM");
+
+ while (m == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ /* it succeeds */
+ g_assert_cmpint (dbus_message_get_type (m), ==,
+ DBUS_MESSAGE_TYPE_METHOD_RETURN);
+
+ dbus_message_unref (m);
+
+ /* Now try with the wrong object path */
+ m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
+ "/com/example/Wrong", DBUS_INTERFACE_DBUS, "UpdateActivationEnvironment");
+
+ if (m == NULL)
+ g_error ("OOM");
+
+ dbus_message_iter_init_append (m, &args_iter);
+
+ /* Append an empty a{ss} (string => string dictionary). */
+ if (!dbus_message_iter_open_container (&args_iter, DBUS_TYPE_ARRAY,
+ "{ss}", &arr_iter) ||
+ !dbus_message_iter_close_container (&args_iter, &arr_iter))
+ g_error ("OOM");
+
+ if (!dbus_connection_send_with_reply (f->left_conn, m, &pc,
+ DBUS_TIMEOUT_USE_DEFAULT) ||
+ pc == NULL)
+ g_error ("OOM");
+
+ dbus_message_unref (m);
+ m = NULL;
+
+ if (dbus_pending_call_get_completed (pc))
+ pending_call_store_reply (pc, &m);
+ else if (!dbus_pending_call_set_notify (pc, pending_call_store_reply,
+ &m, NULL))
+ g_error ("OOM");
+
+ while (m == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ /* it fails, yielding an error message with one string argument */
+ g_assert_cmpint (dbus_message_get_type (m), ==, DBUS_MESSAGE_TYPE_ERROR);
+ g_assert_cmpstr (dbus_message_get_error_name (m), ==,
+ DBUS_ERROR_ACCESS_DENIED);
+ g_assert_cmpstr (dbus_message_get_signature (m), ==, "s");
+
+ dbus_message_unref (m);
+}
+
+static void
teardown (Fixture *f,
gconstpointer context G_GNUC_UNUSED)
{
@@ -700,6 +785,8 @@ main (int argc,
setup, test_no_reply, teardown);
g_test_add ("/creds", Fixture, NULL, setup, test_creds, teardown);
g_test_add ("/processid", Fixture, NULL, setup, test_processid, teardown);
+ g_test_add ("/canonical-path/uae", Fixture, NULL,
+ setup, test_canonical_path_uae, teardown);
return g_test_run ();
}