polkit/loglevel_property_root_only.patch

73 lines
2.6 KiB
Diff

commit 5a4ba7dfdcc3f71e28b5921e71b1685886b46343
Author: Luca Boccassi <luca.boccassi@gmail.com>
Date: Tue Oct 29 13:34:39 2024 +0000
polkit: explicitly restrict setting D-Bus property to root
Unlike sd-bus in libsystemd, gdbus in glib does not automatically
restrict changing properties to the root user. Check the credential
of the caller manually so that changes are restricted as expected.
Also add more user-friendly error messages to other error conditions
for a better user experience.
diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c
index 223dc4a..86ca632 100644
--- a/src/polkitbackend/polkitbackendauthority.c
+++ b/src/polkitbackend/polkitbackendauthority.c
@@ -1439,18 +1439,48 @@ server_handle_set_property (GDBusConnection *connection,
GError **error,
gpointer user_data)
{
+ PolkitSubject *caller_subject;
+ PolkitUnixUser *caller_user;
+ const gchar *level;
+
if (g_strcmp0 (interface_name, "org.freedesktop.LogControl1") != 0)
- return FALSE;
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Only properties of org.freedesktop.LogControl1 can be modified");
+ return FALSE;
+ }
- if (g_strcmp0 (property_name, "LogLevel") == 0)
+ if (g_strcmp0 (property_name, "LogLevel") != 0)
{
- const gchar *level;
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Only LogLevel can be modified");
+ return FALSE;
+ }
- g_variant_get (value, "&s", &level);
- polkit_backend_authority_set_log_level (level);
+ caller_subject = polkit_system_bus_name_new (sender);
+ if (!caller_subject)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Could not obtain caller's credentials");
+ return FALSE;
}
- else
- return FALSE;
+ caller_user = polkit_system_bus_name_get_user_sync (POLKIT_SYSTEM_BUS_NAME (caller_subject), NULL, error);
+ if (!caller_user)
+ {
+ g_object_unref (caller_subject);
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Could not obtain caller's credentials");
+ return FALSE;
+ }
+ if ((uid_t)polkit_unix_user_get_uid (caller_user) != 0)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, "Only root can change the log level");
+ g_object_unref (caller_user);
+ g_object_unref (caller_subject);
+ return FALSE;
+ }
+
+ g_variant_get (value, "&s", &level);
+ polkit_backend_authority_set_log_level (level);
+
+ g_object_unref (caller_user);
+ g_object_unref (caller_subject);
return TRUE;
}