From d8c9138bf240975848b1c54db648ec4cd516a48f Mon Sep 17 00:00:00 2001 From: Simon McVittie <smcv@collabora.com> Date: Wed, 5 Jun 2019 13:33:38 +0100 Subject: [PATCH] gvfsdaemon: Check that the connecting client is the same user Otherwise, an attacker who learns the abstract socket address from netstat(8) or similar could connect to it and issue D-Bus method calls. Signed-off-by: Simon McVittie <smcv@collabora.com> --- daemon/gvfsdaemon.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) Index: gvfs-1.40.1/daemon/gvfsdaemon.c =================================================================== --- gvfs-1.40.1.orig/daemon/gvfsdaemon.c 2019-07-05 08:31:43.293027853 -0400 +++ gvfs-1.40.1/daemon/gvfsdaemon.c 2019-07-05 08:31:43.293027853 -0400 @@ -79,6 +79,7 @@ struct _GVfsDaemon gint mount_counter; + GDBusAuthObserver *auth_observer; GDBusConnection *conn; GVfsDBusDaemon *daemon_skeleton; GVfsDBusMountable *mountable_skeleton; @@ -171,6 +172,8 @@ g_vfs_daemon_finalize (GObject *object) } if (daemon->conn != NULL) g_object_unref (daemon->conn); + if (daemon->auth_observer != NULL) + g_object_unref (daemon->auth_observer); g_hash_table_destroy (daemon->registered_paths); g_hash_table_destroy (daemon->client_connections); @@ -237,6 +240,35 @@ name_vanished_handler (GDBusConnection * daemon->lost_main_daemon = TRUE; } +/* + * Authentication observer signal handler that authorizes connections + * from the same uid as this process. This matches the behaviour of a + * libdbus DBusServer/DBusConnection when no DBusAllowUnixUserFunction + * has been set, but is not the default in GDBus. + */ +static gboolean +authorize_authenticated_peer_cb (GDBusAuthObserver *observer, + G_GNUC_UNUSED GIOStream *stream, + GCredentials *credentials, + G_GNUC_UNUSED gpointer user_data) +{ + gboolean authorized = FALSE; + + if (credentials != NULL) + { + GCredentials *own_credentials; + + own_credentials = g_credentials_new (); + + if (g_credentials_is_same_user (credentials, own_credentials, NULL)) + authorized = TRUE; + + g_object_unref (own_credentials); + } + + return authorized; +} + static void g_vfs_daemon_init (GVfsDaemon *daemon) { @@ -266,6 +298,8 @@ g_vfs_daemon_init (GVfsDaemon *daemon) daemon->conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); g_assert (daemon->conn != NULL); + daemon->auth_observer = g_dbus_auth_observer_new (); + g_signal_connect (daemon->auth_observer, "authorize-authenticated-peer", G_CALLBACK (authorize_authenticated_peer_cb), NULL); daemon->daemon_skeleton = gvfs_dbus_daemon_skeleton_new (); g_signal_connect (daemon->daemon_skeleton, "handle-get-connection", G_CALLBACK (handle_get_connection), daemon); @@ -878,7 +912,7 @@ handle_get_connection (GVfsDBusDaemon *o server = g_dbus_server_new_sync (address1, G_DBUS_SERVER_FLAGS_NONE, guid, - NULL, /* GDBusAuthObserver */ + daemon->auth_observer, NULL, /* GCancellable */ &error); g_free (guid);