diff options
author | Simon McVittie <smcv@collabora.com> | 2017-06-22 18:02:00 +0100 |
---|---|---|
committer | Simon McVittie <smcv@collabora.com> | 2017-12-11 16:03:21 +0000 |
commit | 5619b6f99ea73a6610f764bec9e548d8834af2d0 (patch) | |
tree | 848325becb3aa2bf73eeb751933a1e9a0c14b7dc | |
parent | df837beb2fecb8caaaf6a80669d94d1fd72967a6 (diff) |
bus/containers: Require connecting uid to match caller of AddServer
If we're strict now, we can relax this later (either with a named
parameter or always); but if we're lenient now, we'll be stuck with it
forever, so be strict.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Reviewed-by: Philip Withnall <withnall@endlessm.com>
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=101354
-rw-r--r-- | bus/containers.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/bus/containers.c b/bus/containers.c index 5bb8fc6a..6d32368e 100644 --- a/bus/containers.c +++ b/bus/containers.c @@ -31,6 +31,8 @@ # error DBUS_ENABLE_CONTAINERS requires DBUS_UNIX #endif +#include <sys/types.h> + #include "dbus/dbus-hash.h" #include "dbus/dbus-message-internal.h" #include "dbus/dbus-sysdeps-unix.h" @@ -52,6 +54,7 @@ typedef struct BusContext *context; BusContainers *containers; DBusServer *server; + unsigned long uid; } BusContainerInstance; /* @@ -284,6 +287,22 @@ static const char * const auth_mechanisms[] = NULL }; +/* Statically assert that we can store a uid in a void *, losslessly. + * + * In practice this is always true on Unix. For now we don't support this + * feature on systems where it isn't. */ +_DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (uintptr_t)); +/* True by definition. */ +_DBUS_STATIC_ASSERT (sizeof (void *) == sizeof (uintptr_t)); + +static dbus_bool_t +allow_same_uid_only (DBusConnection *connection, + unsigned long uid, + void *data) +{ + return (uid == (uintptr_t) data); +} + static void new_connection_cb (DBusServer *server, DBusConnection *new_connection, @@ -294,6 +313,23 @@ new_connection_cb (DBusServer *server, /* If this fails it logs a warning, so we don't need to do that */ if (!bus_context_add_incoming_connection (instance->context, new_connection)) return; + + /* We'd like to check the uid here, but we can't yet. Instead clear the + * BusContext's unix_user_function, which results in us getting the + * default behaviour: only the user that owns the bus can connect. + * + * TODO: For the system bus we might want a way to opt-in to allowing + * other uids, in which case we would refrain from overwriting the + * BusContext's unix_user_function; but that isn't part of the + * lowest-common-denominator implementation. */ + dbus_connection_set_unix_user_function (new_connection, + allow_same_uid_only, + /* The static assertion above + * allow_same_uid_only ensures that + * this cast does not lose + * information */ + (void *) (uintptr_t) instance->uid, + NULL); } static const char * @@ -432,6 +468,13 @@ bus_containers_handle_add_server (DBusConnection *connection, if (instance == NULL) goto fail; + if (!dbus_connection_get_unix_user (connection, &instance->uid)) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Unable to determine user ID of caller"); + goto fail; + } + /* We already checked this in bus_driver_handle_message() */ _dbus_assert (dbus_message_has_signature (message, "ssa{sv}a{sv}")); |