From 81ca03541a0b4c72570b65875ce03c6be86e753b Mon Sep 17 00:00:00 2001 From: Mateusz Moscicki Date: Tue, 20 Jun 2023 13:15:22 +0200 Subject: [PATCH] Allow to change the default connection type to private This is used to ensure that applications launched by launchpad get their own connection with the appropriate label, rather than using the connection that was established before the label change. Change-Id: Id1a6c80638c762f3de8856410b562df653dd70b5 --- src/libgdbus/libgdbus.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- src/libgdbus/libgdbus.h | 2 ++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/libgdbus/libgdbus.c b/src/libgdbus/libgdbus.c index 32c15ed..3046ab1 100644 --- a/src/libgdbus/libgdbus.c +++ b/src/libgdbus/libgdbus.c @@ -34,6 +34,7 @@ #define DBUS_REPLY_TIMEOUT (10000) static GBusType g_default_bus_type = G_BUS_TYPE_SYSTEM; +static gboolean g_default_priv = false; pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; void gdbus_set_default_bus_type(GBusType bus_type) @@ -93,9 +94,13 @@ typedef struct { static dbus_handle_s g_dh[2]; static dbus_handle_s *_gdbus_get_connection(GBusType bus_type); +static dbus_handle_s *_gdbus_get_connection_private(GBusType bus_type); dbus_handle_s * _gdbus_get_default_connection(void) { + if (g_default_priv) + return _gdbus_get_connection_private(gdbus_get_default_bus_type()); + return _gdbus_get_connection(gdbus_get_default_bus_type()); } @@ -559,7 +564,7 @@ char **gdbus_get_owner_list(dbus_handle_h handle, const char *bus_name) return strv; } -int gdbus_free_connection(dbus_handle_h handle) +int _gdbus_free_connection(dbus_handle_h handle, gboolean close_any_connection) { dcl_gdbus(); dbus_handle_s *pdh = NULL; @@ -643,8 +648,8 @@ int gdbus_free_connection(dbus_handle_h handle) } /* close connection */ - if (pdh->priv) { - _E("close private connection\n"); + if (pdh->priv || close_any_connection) { + _E("close connection\n"); if (!g_dbus_connection_close_sync(pdh->conn, NULL, &err)) { _E("Error closing connection %s\n", err->message); @@ -669,6 +674,12 @@ int gdbus_free_connection(dbus_handle_h handle) // todo: signal ? } +int gdbus_free_connection(dbus_handle_h handle) +{ + return _gdbus_free_connection(handle, false); +} + + #define buf_cal_free_space(size, nwrite) ((size - nwrite - 1) > 0 ? (size - nwrite - 1) : 0) #define buf_block_size 8192 @@ -2882,3 +2893,31 @@ GVariant *gdbus_make_simple_array(const char *sig, int *param) g_variant_builder_unref(builder); return var; } + +int gdbus_switch_to_private_connection(void) +{ + // This function is called by launchpad during the application preparation + // process. Launchpad is running with high privileges (label User). If a call + // to dbus is made before the process privileges are changed to lower (wich is + // what happens now), any method call sent with this connection will be + // visible as a call from a privileged process. + // + // From outside glib we can't effectively close the current connection so as + // to receive a new one (with application label), so this function forces to + // use of a private connection. + + // Close current connection so that it can not be used. + dbus_handle_s *connection = _gdbus_get_connection(gdbus_get_default_bus_type()); + int ret; + if ((ret = _gdbus_free_connection(connection, true)) != 0) + return ret; + + // Switch to a private connection. + pthread_mutex_lock(&g_mutex); + g_default_priv = true; + pthread_mutex_unlock(&g_mutex); + + _I("Switched to private connection."); + + return 0; +} diff --git a/src/libgdbus/libgdbus.h b/src/libgdbus/libgdbus.h index 659b2e4..8313715 100644 --- a/src/libgdbus/libgdbus.h +++ b/src/libgdbus/libgdbus.h @@ -278,6 +278,8 @@ GVariant *gdbus_make_simple_array (const char *sig, int check_systemd_active (void); +int gdbus_switch_to_private_connection (void); + #ifdef __cplusplus } #endif -- 2.7.4