[glib: 2/7] gdbusprivate: Validate machine ID after loading it




commit daa62a35e15a794623167b860505b9b28b37dddc
Author: Philip Withnall <pwithnall endlessos org>
Date:   Wed Feb 24 11:49:47 2021 +0000

    gdbusprivate: Validate machine ID after loading it
    
    It’s unlikely that the machine ID will be invalid (it’s system
    configuration), but it would be helpful to not propagate invalid IDs
    further, since a lot of things rely on it.
    
    It’s not easy to test this (it requires factoring out the code so it can
    be used from a test program, or allowing it to load a machine ID from a
    custom path), so I haven’t added unit tests. I’ve tested manually by
    overriding the loaded machine ID.
    
    Coverity CID: #1430944
    
    Signed-off-by: Philip Withnall <pwithnall endlessos org>

 gio/gdbusprivate.c | 40 +++++++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 7 deletions(-)
---
diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c
index 70c098582..8bb52227a 100644
--- a/gio/gdbusprivate.c
+++ b/gio/gdbusprivate.c
@@ -2472,6 +2472,8 @@ _g_dbus_get_machine_id (GError **error)
 #else
   gchar *ret = NULL;
   GError *first_error = NULL;
+  gsize i;
+  gboolean non_zero = FALSE;
 
   /* TODO: use PACKAGE_LOCALSTATEDIR ? */
   if (!g_file_get_contents ("/var/lib/dbus/machine-id",
@@ -2483,17 +2485,41 @@ _g_dbus_get_machine_id (GError **error)
                             NULL,
                             NULL))
     {
-      g_propagate_prefixed_error (error, first_error,
+      g_propagate_prefixed_error (error, g_steal_pointer (&first_error),
                                   _("Unable to load /var/lib/dbus/machine-id or /etc/machine-id: "));
+      return NULL;
     }
-  else
+
+  /* ignore the error from the first try, if any */
+  g_clear_error (&first_error);
+
+  /* Validate the machine ID. From `man 5 machine-id`:
+   * > The machine ID is a single newline-terminated, hexadecimal, 32-character,
+   * > lowercase ID. When decoded from hexadecimal, this corresponds to a
+   * > 16-byte/128-bit value. This ID may not be all zeros.
+   */
+  for (i = 0; ret[i] != '\0' && ret[i] != '\n'; i++)
     {
-      /* ignore the error from the first try, if any */
-      g_clear_error (&first_error);
-      /* TODO: validate value */
-      g_strstrip (ret);
+      /* Break early if it’s invalid. */
+      if (!g_ascii_isxdigit (ret[i]) || g_ascii_isupper (ret[i]))
+        break;
+
+      if (ret[i] != '0')
+        non_zero = TRUE;
     }
-  return ret;
+
+  if (i != 32 || ret[i] != '\n' || ret[i + 1] != '\0' || !non_zero)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "Invalid machine ID in /var/lib/dbus/machine-id or /etc/machine-id");
+      g_free (ret);
+      return NULL;
+    }
+
+  /* Strip trailing newline. */
+  ret[32] = '\0';
+
+  return g_steal_pointer (&ret);
 #endif
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]