From b3de9ffd213e105995e80cedff9e04560da83bf1 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 14 Apr 2022 09:11:24 -0500 Subject: [PATCH] Add support for a new TrustedUids key This key is used to specify that a dedicated user runs the fwupd client process and sensitive strings such as the serial number should be shared with the calling process. (Fixes: #4524) --- data/daemon.conf | 3 +++ src/fu-config.c | 25 +++++++++++++++++++++++++ src/fu-config.h | 2 ++ src/fu-engine.c | 17 +++++++++++++++++ src/fu-engine.h | 2 ++ src/fu-main.c | 2 +- 6 files changed, 50 insertions(+), 1 deletion(-) diff --git a/data/daemon.conf b/data/daemon.conf index 83f12a6e1..6ac825249 100644 --- a/data/daemon.conf +++ b/data/daemon.conf @@ -52,6 +52,9 @@ OnlyTrusted=true # Show private data like device serial numbers and instance IDs to clients ShowDevicePrivate=true +# UIDs that should marked as trusted +TrustedUids= + # A host best known configuration is used when using `fwupdmgr sync` which can # downgrade firmware to factory versions or upgrade firmware to a supported # config level. e.g. `vendor-factory-2021q1` diff --git a/src/fu-config.c b/src/fu-config.c index 0dd9ec0df..3457f0b43 100644 --- a/src/fu-config.c +++ b/src/fu-config.c @@ -30,6 +30,7 @@ struct _FuConfig { GPtrArray *blocked_firmware; /* (element-type utf-8) */ GPtrArray *uri_schemes; /* (element-type utf-8) */ GPtrArray *filenames; /* (element-type utf-8) */ + GArray *trusted_uids; /* (elementy type guint64) */ guint64 archive_size_max; guint idle_timeout; gchar *host_bkc; @@ -58,6 +59,7 @@ fu_config_reload(FuConfig *self, GError **error) g_auto(GStrv) blocked_firmware = NULL; g_auto(GStrv) uri_schemes = NULL; g_auto(GStrv) devices = NULL; + g_auto(GStrv) uids = NULL; g_auto(GStrv) plugins = NULL; g_autofree gchar *domains = NULL; g_autofree gchar *host_bkc = NULL; @@ -241,6 +243,20 @@ fu_config_reload(FuConfig *self, GError **error) if (host_bkc != NULL && host_bkc[0] != '\0') self->host_bkc = g_steal_pointer(&host_bkc); + /* get trusted uids */ + g_array_set_size(self->trusted_uids, 0); + uids = g_key_file_get_string_list(keyfile, + "fwupd", + "TrustedUids", + NULL, /* length */ + NULL); + if (uids != NULL) { + for (guint i = 0; uids[i] != NULL; i++) { + guint64 val = fu_common_strtoull(uids[i]); + g_array_append_val(self->trusted_uids, val); + } + } + return TRUE; } @@ -332,6 +348,13 @@ fu_config_get_disabled_devices(FuConfig *self) return self->disabled_devices; } +GArray * +fu_config_get_trusted_uids(FuConfig *self) +{ + g_return_val_if_fail(FU_IS_CONFIG(self), NULL); + return self->trusted_uids; +} + GPtrArray * fu_config_get_blocked_firmware(FuConfig *self) { @@ -451,6 +474,7 @@ fu_config_init(FuConfig *self) self->disabled_plugins = g_ptr_array_new_with_free_func(g_free); self->approved_firmware = g_ptr_array_new_with_free_func(g_free); self->blocked_firmware = g_ptr_array_new_with_free_func(g_free); + self->trusted_uids = g_array_new(FALSE, FALSE, sizeof(guint64)); self->uri_schemes = g_ptr_array_new_with_free_func(g_free); self->monitors = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref); } @@ -471,6 +495,7 @@ fu_config_finalize(GObject *obj) g_ptr_array_unref(self->approved_firmware); g_ptr_array_unref(self->blocked_firmware); g_ptr_array_unref(self->uri_schemes); + g_array_unref(self->trusted_uids); g_free(self->host_bkc); G_OBJECT_CLASS(fu_config_parent_class)->finalize(obj); diff --git a/src/fu-config.h b/src/fu-config.h index 86381b171..4ea3fc1c0 100644 --- a/src/fu-config.h +++ b/src/fu-config.h @@ -28,6 +28,8 @@ GPtrArray * fu_config_get_disabled_devices(FuConfig *self); GPtrArray * fu_config_get_disabled_plugins(FuConfig *self); +GArray * +fu_config_get_trusted_uids(FuConfig *self); GPtrArray * fu_config_get_approved_firmware(FuConfig *self); GPtrArray * diff --git a/src/fu-engine.c b/src/fu-engine.c index 33555611a..f84409a60 100644 --- a/src/fu-engine.c +++ b/src/fu-engine.c @@ -5770,6 +5770,23 @@ fu_engine_add_plugin(FuEngine *self, FuPlugin *plugin) fu_plugin_list_add(self->plugin_list, plugin); } +gboolean +fu_engine_is_uid_trusted(FuEngine *self, guint64 calling_uid) +{ + GArray *trusted; + + /* root is always trusted */ + if (calling_uid == 0) + return TRUE; + + trusted = fu_config_get_trusted_uids(self->config); + for (guint i = 0; i < trusted->len; i++) { + if (calling_uid == g_array_index(trusted, guint64, i)) + return TRUE; + } + return FALSE; +} + static gboolean fu_engine_is_plugin_name_disabled(FuEngine *self, const gchar *name) { diff --git a/src/fu-engine.h b/src/fu-engine.h index d6ee617e3..ca6aa3d4a 100644 --- a/src/fu-engine.h +++ b/src/fu-engine.h @@ -68,6 +68,8 @@ const gchar * fu_engine_get_host_machine_id(FuEngine *self); const gchar * fu_engine_get_host_bkc(FuEngine *self); +gboolean +fu_engine_is_uid_trusted(FuEngine *self, guint64 calling_uid); const gchar * fu_engine_get_host_security_id(FuEngine *self); FwupdStatus diff --git a/src/fu-main.c b/src/fu-main.c index 61da7aa46..8cfa911ac 100644 --- a/src/fu-main.c +++ b/src/fu-main.c @@ -284,7 +284,7 @@ fu_main_create_request(FuMainPrivate *priv, const gchar *sender, GError **error) return NULL; } g_variant_get(value, "(u)", &calling_uid); - if (calling_uid == 0) + if (fu_engine_is_uid_trusted(priv->engine, calling_uid)) device_flags |= FWUPD_DEVICE_FLAG_TRUSTED; fu_engine_request_set_device_flags(request, device_flags);