commit e062c17e3829f3c04c25b5f6fc17ccc4491befa8
Author: Tomas Bzatek <tbzatek@redhat.com>
Date: Tue Mar 23 16:48:08 2021 +0100
modules: Limit module name to alphanumeric characters and -_ separators
A hardening feature as long as the module name is directly involved
in filename creation.
diff --git a/doc/udisks2-sections.txt.daemon.sections.in b/doc/udisks2-sections.txt.daemon.sections.in
index 16eaf74e..204ca897 100644
--- a/doc/udisks2-sections.txt.daemon.sections.in
+++ b/doc/udisks2-sections.txt.daemon.sections.in
@@ -312,6 +312,7 @@ udisks_daemon_util_get_free_mdraid_device
udisks_ata_identify_get_word
udisks_daemon_util_trigger_uevent
udisks_daemon_util_trigger_uevent_sync
+udisks_module_validate_name
</SECTION>
<SECTION>
diff --git a/src/udisksconfigmanager.c b/src/udisksconfigmanager.c
index 9558e276..5868e864 100644
--- a/src/udisksconfigmanager.c
+++ b/src/udisksconfigmanager.c
@@ -26,6 +26,7 @@
#include "udiskslogging.h"
#include "udisksdaemontypes.h"
#include "udisksconfigmanager.h"
+#include "udisksdaemonutil.h"
struct _UDisksConfigManager {
GObject parent_instance;
@@ -60,6 +61,8 @@ enum
#define DEFAULTS_GROUP_NAME "defaults"
#define DEFAULTS_ENCRYPTION_KEY "encryption"
+#define MODULES_ALL_ARG "*"
+
static void
udisks_config_manager_get_property (GObject *object,
guint property_id,
@@ -170,7 +173,16 @@ parse_config_file (UDisksConfigManager *manager,
{
modules_tmp = modules;
for (module_i = *modules_tmp; module_i; module_i = *++modules_tmp)
- *out_modules = g_list_append (*out_modules, g_strdup (g_strstrip (module_i)));
+ {
+ g_strstrip (module_i);
+ if (! udisks_module_validate_name (module_i) && !g_str_equal (module_i, MODULES_ALL_ARG))
+ {
+ g_warning ("Invalid module name '%s' specified in the %s config file.",
+ module_i, conf_filename);
+ continue;
+ }
+ *out_modules = g_list_append (*out_modules, g_strdup (module_i));
+ }
g_strfreev (modules);
}
}
@@ -397,7 +409,7 @@ udisks_config_manager_get_modules_all (UDisksConfigManager *manager)
parse_config_file (manager, NULL, NULL, &modules);
- ret = !modules || (g_strcmp0 (modules->data, "*") == 0 && g_list_length (modules) == 1);
+ ret = !modules || (g_strcmp0 (modules->data, MODULES_ALL_ARG) == 0 && g_list_length (modules) == 1);
g_list_free_full (modules, (GDestroyNotify) g_free);
diff --git a/src/udisksdaemonutil.c b/src/udisksdaemonutil.c
index 60134765..1695b524 100644
--- a/src/udisksdaemonutil.c
+++ b/src/udisksdaemonutil.c
@@ -1880,3 +1880,29 @@ udisks_daemon_util_trigger_uevent_sync (UDisksDaemon *daemon,
}
/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * udisks_module_validate_name:
+ * @module_name: A udisks2 module name.
+ *
+ * Checks the string for a valid udisks2 module name. Only alphanumeric characters
+ * along with the '-' and '_' separators are permitted.
+ *
+ * Returns: %TRUE if the string is a valid udisks2 module name, %FALSE otherwise.
+ */
+gboolean
+udisks_module_validate_name (const gchar *module_name)
+{
+ int i;
+
+ for (i = 0; module_name[i] != '\0'; i++)
+ /* going ASCII, will disqualify any UTF-* string */
+ if (! g_ascii_isalnum (module_name[i]) &&
+ module_name[i] != '-' &&
+ module_name[i] != '_')
+ return FALSE;
+
+ return TRUE;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/udisksdaemonutil.h b/src/udisksdaemonutil.h
index 2d7ac981..df584de4 100644
--- a/src/udisksdaemonutil.h
+++ b/src/udisksdaemonutil.h
@@ -129,6 +129,8 @@ gchar *udisks_daemon_util_get_free_mdraid_device (void);
guint16 udisks_ata_identify_get_word (const guchar *identify_data, guint word_number);
+gboolean udisks_module_validate_name (const gchar *module_name);
+
/* Utility macro for policy verification. */
#define UDISKS_DAEMON_CHECK_AUTHORIZATION(daemon, \
object, \
diff --git a/src/udiskslinuxmanager.c b/src/udiskslinuxmanager.c
index 8af65d97..26d8a5d7 100644
--- a/src/udiskslinuxmanager.c
+++ b/src/udiskslinuxmanager.c
@@ -956,6 +956,15 @@ handle_enable_module (UDisksManager *object,
UDisksLinuxManager *manager = UDISKS_LINUX_MANAGER (object);
EnableModulesData *data;
+ if (! udisks_module_validate_name (arg_name))
+ {
+ g_dbus_method_invocation_return_error (invocation,
+ G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ "Requested module name '%s' is not a valid udisks2 module name.",
+ arg_name);
+ return TRUE;
+ }
+
if (! arg_enable)
{
/* TODO: implement proper module unloading */