|
|
8d3db5 |
From 3d442dbf936d197aa11ca0a71663c2bc61696151 Mon Sep 17 00:00:00 2001
|
|
|
8d3db5 |
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
|
8d3db5 |
Date: Fri, 13 Sep 2019 15:59:03 +0900
|
|
|
8d3db5 |
Subject: [PATCH] bus: Implement GDBusAuthObserver callback
|
|
|
8d3db5 |
|
|
|
8d3db5 |
ibus uses a GDBusServer with G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS,
|
|
|
8d3db5 |
and doesn't set a GDBusAuthObserver, which allows anyone who can connect
|
|
|
8d3db5 |
to its AF_UNIX socket to authenticate and be authorized to send method calls.
|
|
|
8d3db5 |
It also seems to use an abstract AF_UNIX socket, which does not have
|
|
|
8d3db5 |
filesystem permissions, so the practical effect might be that a local
|
|
|
8d3db5 |
attacker can connect to another user's ibus service and make arbitrary
|
|
|
8d3db5 |
method calls.
|
|
|
8d3db5 |
|
|
|
8d3db5 |
BUGS=rhbz#1717958
|
|
|
8d3db5 |
---
|
|
|
8d3db5 |
bus/server.c | 89 ++++++++++++++++++++++++++++++++++++++++++----------
|
|
|
8d3db5 |
1 file changed, 73 insertions(+), 16 deletions(-)
|
|
|
8d3db5 |
|
|
|
8d3db5 |
diff --git a/bus/server.c b/bus/server.c
|
|
|
8d3db5 |
index 3a626230..2439de14 100644
|
|
|
8d3db5 |
--- a/bus/server.c
|
|
|
8d3db5 |
+++ b/bus/server.c
|
|
|
8d3db5 |
@@ -2,7 +2,8 @@
|
|
|
8d3db5 |
/* vim:set et sts=4: */
|
|
|
8d3db5 |
/* bus - The Input Bus
|
|
|
8d3db5 |
* Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
|
|
|
8d3db5 |
- * Copyright (C) 2008-2010 Red Hat, Inc.
|
|
|
8d3db5 |
+ * Copyright (C) 2011-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
|
8d3db5 |
+ * Copyright (C) 2008-2019 Red Hat, Inc.
|
|
|
8d3db5 |
*
|
|
|
8d3db5 |
* This library is free software; you can redistribute it and/or
|
|
|
8d3db5 |
* modify it under the terms of the GNU Lesser General Public
|
|
|
8d3db5 |
@@ -70,16 +71,63 @@ _restart_server (void)
|
|
|
8d3db5 |
}
|
|
|
8d3db5 |
|
|
|
8d3db5 |
/**
|
|
|
8d3db5 |
+ * bus_allow_mechanism_cb:
|
|
|
8d3db5 |
+ * @observer: A #GDBusAuthObserver.
|
|
|
8d3db5 |
+ * @mechanism: The name of the mechanism.
|
|
|
8d3db5 |
+ * @user_data: always %NULL.
|
|
|
8d3db5 |
+ *
|
|
|
8d3db5 |
+ * Check if @mechanism can be used to authenticate the other peer.
|
|
|
8d3db5 |
+ * Returns: %TRUE if the peer's mechanism is allowed.
|
|
|
8d3db5 |
+ */
|
|
|
8d3db5 |
+static gboolean
|
|
|
8d3db5 |
+bus_allow_mechanism_cb (GDBusAuthObserver *observer,
|
|
|
8d3db5 |
+ const gchar *mechanism,
|
|
|
8d3db5 |
+ G_GNUC_UNUSED gpointer user_data)
|
|
|
8d3db5 |
+{
|
|
|
8d3db5 |
+ if (g_strcmp0 (mechanism, "EXTERNAL") == 0)
|
|
|
8d3db5 |
+ return TRUE;
|
|
|
8d3db5 |
+ return FALSE;
|
|
|
8d3db5 |
+}
|
|
|
8d3db5 |
+
|
|
|
8d3db5 |
+/**
|
|
|
8d3db5 |
+ * bus_authorize_authenticated_peer_cb:
|
|
|
8d3db5 |
+ * @observer: A #GDBusAuthObserver.
|
|
|
8d3db5 |
+ * @stream: A #GIOStream.
|
|
|
8d3db5 |
+ * @credentials: A #GCredentials.
|
|
|
8d3db5 |
+ * @user_data: always %NULL.
|
|
|
8d3db5 |
+ *
|
|
|
8d3db5 |
+ * Check if a peer who has already authenticated should be authorized.
|
|
|
8d3db5 |
+ * Returns: %TRUE if the peer's credential is authorized.
|
|
|
8d3db5 |
+ */
|
|
|
8d3db5 |
+static gboolean
|
|
|
8d3db5 |
+bus_authorize_authenticated_peer_cb (GDBusAuthObserver *observer,
|
|
|
8d3db5 |
+ GIOStream *stream,
|
|
|
8d3db5 |
+ GCredentials *credentials,
|
|
|
8d3db5 |
+ G_GNUC_UNUSED gpointer user_data)
|
|
|
8d3db5 |
+{
|
|
|
8d3db5 |
+ gboolean authorized = FALSE;
|
|
|
8d3db5 |
+ if (credentials) {
|
|
|
8d3db5 |
+ GCredentials *own_credentials = g_credentials_new ();
|
|
|
8d3db5 |
+ if (g_credentials_is_same_user (credentials, own_credentials, NULL))
|
|
|
8d3db5 |
+ authorized = TRUE;
|
|
|
8d3db5 |
+ g_object_unref (own_credentials);
|
|
|
8d3db5 |
+ }
|
|
|
8d3db5 |
+ return authorized;
|
|
|
8d3db5 |
+}
|
|
|
8d3db5 |
+
|
|
|
8d3db5 |
+/**
|
|
|
8d3db5 |
* bus_new_connection_cb:
|
|
|
8d3db5 |
- * @user_data: always NULL.
|
|
|
8d3db5 |
- * @returns: TRUE when the function can handle the connection.
|
|
|
8d3db5 |
+ * @observer: A #GDBusAuthObserver.
|
|
|
8d3db5 |
+ * @dbus_connection: A #GDBusconnection.
|
|
|
8d3db5 |
+ * @user_data: always %NULL.
|
|
|
8d3db5 |
*
|
|
|
8d3db5 |
* Handle incoming connections.
|
|
|
8d3db5 |
+ * Returns: %TRUE when the function can handle the connection.
|
|
|
8d3db5 |
*/
|
|
|
8d3db5 |
static gboolean
|
|
|
8d3db5 |
-bus_new_connection_cb (GDBusServer *server,
|
|
|
8d3db5 |
- GDBusConnection *dbus_connection,
|
|
|
8d3db5 |
- gpointer user_data)
|
|
|
8d3db5 |
+bus_new_connection_cb (GDBusServer *server,
|
|
|
8d3db5 |
+ GDBusConnection *dbus_connection,
|
|
|
8d3db5 |
+ G_GNUC_UNUSED gpointer user_data)
|
|
|
8d3db5 |
{
|
|
|
8d3db5 |
BusConnection *connection = bus_connection_new (dbus_connection);
|
|
|
8d3db5 |
bus_dbus_impl_new_connection (dbus, connection);
|
|
|
8d3db5 |
@@ -94,9 +142,9 @@ bus_new_connection_cb (GDBusServer *
|
|
|
8d3db5 |
}
|
|
|
8d3db5 |
|
|
|
8d3db5 |
static void
|
|
|
8d3db5 |
-_server_connect_start_portal_cb (GObject *source_object,
|
|
|
8d3db5 |
- GAsyncResult *res,
|
|
|
8d3db5 |
- gpointer user_data)
|
|
|
8d3db5 |
+_server_connect_start_portal_cb (GObject *source_object,
|
|
|
8d3db5 |
+ GAsyncResult *res,
|
|
|
8d3db5 |
+ G_GNUC_UNUSED gpointer user_data)
|
|
|
8d3db5 |
{
|
|
|
8d3db5 |
GVariant *result;
|
|
|
8d3db5 |
GError *error = NULL;
|
|
|
8d3db5 |
@@ -113,9 +161,9 @@ _server_connect_start_portal_cb (GObject
|
|
|
8d3db5 |
}
|
|
|
8d3db5 |
|
|
|
8d3db5 |
static void
|
|
|
8d3db5 |
-bus_acquired_handler (GDBusConnection *connection,
|
|
|
8d3db5 |
- const gchar *name,
|
|
|
8d3db5 |
- gpointer user_data)
|
|
|
8d3db5 |
+bus_acquired_handler (GDBusConnection *connection,
|
|
|
8d3db5 |
+ const gchar *name,
|
|
|
8d3db5 |
+ G_GNUC_UNUSED gpointer user_data)
|
|
|
8d3db5 |
{
|
|
|
8d3db5 |
g_dbus_connection_call (connection,
|
|
|
8d3db5 |
IBUS_SERVICE_PORTAL,
|
|
|
8d3db5 |
@@ -136,22 +184,27 @@ void
|
|
|
8d3db5 |
bus_server_init (void)
|
|
|
8d3db5 |
{
|
|
|
8d3db5 |
GError *error = NULL;
|
|
|
8d3db5 |
+ GDBusServerFlags flags = G_DBUS_SERVER_FLAGS_NONE;
|
|
|
8d3db5 |
+ gchar *guid;
|
|
|
8d3db5 |
+ GDBusAuthObserver *observer;
|
|
|
8d3db5 |
|
|
|
8d3db5 |
dbus = bus_dbus_impl_get_default ();
|
|
|
8d3db5 |
ibus = bus_ibus_impl_get_default ();
|
|
|
8d3db5 |
bus_dbus_impl_register_object (dbus, (IBusService *)ibus);
|
|
|
8d3db5 |
|
|
|
8d3db5 |
/* init server */
|
|
|
8d3db5 |
- GDBusServerFlags flags = G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
|
|
|
8d3db5 |
- gchar *guid = g_dbus_generate_guid ();
|
|
|
8d3db5 |
- if (!g_str_has_prefix (g_address, "unix:tmpdir=")) {
|
|
|
8d3db5 |
- g_error ("Your socket address does not have the format unix:tmpdir=$DIR; %s",
|
|
|
8d3db5 |
- g_address);
|
|
|
8d3db5 |
+ guid = g_dbus_generate_guid ();
|
|
|
8d3db5 |
+ observer = g_dbus_auth_observer_new ();
|
|
|
8d3db5 |
+ if (!g_str_has_prefix (g_address, "unix:tmpdir=") &&
|
|
|
8d3db5 |
+ !g_str_has_prefix (g_address, "unix:path=")) {
|
|
|
8d3db5 |
+ g_error ("Your socket address does not have the format unix:tmpdir=$DIR "
|
|
|
8d3db5 |
+ "or unix:path=$FILE; %s", g_address);
|
|
|
8d3db5 |
+
|
|
|
8d3db5 |
}
|
|
|
8d3db5 |
server = g_dbus_server_new_sync (
|
|
|
8d3db5 |
g_address, /* the place where the socket file lives, e.g. /tmp, abstract namespace, etc. */
|
|
|
8d3db5 |
flags, guid,
|
|
|
8d3db5 |
- NULL /* observer */,
|
|
|
8d3db5 |
+ observer,
|
|
|
8d3db5 |
NULL /* cancellable */,
|
|
|
8d3db5 |
&error);
|
|
|
8d3db5 |
if (server == NULL) {
|
|
|
8d3db5 |
@@ -161,7 +214,13 @@ bus_server_init (void)
|
|
|
8d3db5 |
}
|
|
|
8d3db5 |
g_free (guid);
|
|
|
8d3db5 |
|
|
|
8d3db5 |
- g_signal_connect (server, "new-connection", G_CALLBACK (bus_new_connection_cb), NULL);
|
|
|
8d3db5 |
+ g_signal_connect (observer, "allow-mechanism",
|
|
|
8d3db5 |
+ G_CALLBACK (bus_allow_mechanism_cb), NULL);
|
|
|
8d3db5 |
+ g_signal_connect (observer, "authorize-authenticated-peer",
|
|
|
8d3db5 |
+ G_CALLBACK (bus_authorize_authenticated_peer_cb), NULL);
|
|
|
8d3db5 |
+ g_object_unref (observer);
|
|
|
8d3db5 |
+ g_signal_connect (server, "new-connection",
|
|
|
8d3db5 |
+ G_CALLBACK (bus_new_connection_cb), NULL);
|
|
|
8d3db5 |
|
|
|
8d3db5 |
g_dbus_server_start (server);
|
|
|
8d3db5 |
|
|
|
8d3db5 |
--
|
|
|
8d3db5 |
2.21.0
|
|
|
8d3db5 |
|