summaryrefslogtreecommitdiff
path: root/bus
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2015-01-01 23:48:13 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2015-01-01 23:48:13 +0000
commitae9d7149aa9a9f8f276c35b2343e78aaa7c9054c (patch)
tree8697326f4c120119e825b82f96bd239002de3712 /bus
parentfda9d8a44aa1bde4f2777fb9ad8650f45820fb6b (diff)
parentabbbf449f17e0a74a5d9a50fb5b074e96e9b7030 (diff)
downloaddbus-ae9d7149aa9a9f8f276c35b2343e78aaa7c9054c.tar.gz
Merge branch 'dbus-1.8' and prepare 1.9.6dbus-1.9.6
Conflicts: NEWS configure.ac test/dbus-daemon.c
Diffstat (limited to 'bus')
-rw-r--r--bus/driver.c70
-rw-r--r--bus/driver.h4
-rw-r--r--bus/stats.c7
3 files changed, 79 insertions, 2 deletions
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,