diff options
author | Simon McVittie <smcv@debian.org> | 2015-01-02 11:12:04 +0000 |
---|---|---|
committer | Simon McVittie <smcv@debian.org> | 2015-01-02 11:12:04 +0000 |
commit | f116122d73d42c91b292a56a71a7767e2347abe9 (patch) | |
tree | f318e04930bf2ea42d01263111994e2a79eb767f | |
parent | 4d4030d319dbe92f18906f8ec947d964dbab3c1b (diff) | |
parent | 226e9039099f3c04e9bbf474a3b145a681ac4a2f (diff) | |
download | dbus-f116122d73d42c91b292a56a71a7767e2347abe9.tar.gz |
Merge tag 'upstream/1.9.6' into experimental
Upstream version 1.9.6
-rw-r--r-- | NEWS | 31 | ||||
-rw-r--r-- | bus/driver.c | 70 | ||||
-rw-r--r-- | bus/driver.h | 4 | ||||
-rw-r--r-- | bus/stats.c | 7 | ||||
-rwxr-xr-x | configure | 26 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | dbus/dbus-sysdeps-win.c | 2 | ||||
-rw-r--r-- | doc/dbus-specification.xml | 10 | ||||
-rw-r--r-- | test/dbus-daemon.c | 87 |
9 files changed, 222 insertions, 19 deletions
@@ -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, @@ -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 (); } |