Blob Blame History Raw
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 */