[dconf] engine: reject junk signals



commit 0a8e738d62fc99466b39f4f25d4c9e343fe8199c
Author: Ryan Lortie <desrt desrt ca>
Date:   Wed Nov 27 14:00:21 2013 -0500

    engine: reject junk signals
    
    Check incoming signals for non-sense before bubbling them up to higher
    layers.  This will avoid dconf APIs feeding invalid key names to
    applications during change notifications in the case that we're fed
    invalid data over D-Bus.

 engine/dconf-engine.c |   36 ++++++++++++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)
---
diff --git a/engine/dconf-engine.c b/engine/dconf-engine.c
index 5e1ee7e..50a461b 100644
--- a/engine/dconf-engine.c
+++ b/engine/dconf-engine.c
@@ -25,6 +25,7 @@
 #include "dconf-engine.h"
 
 #include "../common/dconf-error.h"
+#include "../common/dconf-paths.h"
 #include "../gvdb/gvdb-reader.h"
 #include <string.h>
 #include <stdlib.h>
@@ -1219,6 +1220,36 @@ dconf_engine_handle_dbus_signal (GBusType     type,
 
       g_variant_get (body, "(&s^a&s&s)", &prefix, &changes, &tag);
 
+      /* Reject junk */
+      if (changes[0] == NULL)
+        /* No changes?  Do nothing. */
+        goto junk;
+
+      if (dconf_is_key (prefix, NULL))
+        {
+          /* If the prefix is a key then the changes must be ['']. */
+          if (changes[0][0] || changes[1])
+            goto junk;
+        }
+      else if (dconf_is_dir (prefix, NULL))
+        {
+          /* If the prefix is a dir then we can have changes within that
+           * dir, but they must be rel paths.
+           *
+           *   ie:
+           *
+           *  ('/a/', ['b', 'c/']) == ['/a/b', '/a/c/']
+           */
+          gint i;
+
+          for (i = 0; changes[i]; i++)
+            if (!dconf_is_rel_path (changes[i], NULL))
+              goto junk;
+        }
+      else
+        /* Not a key or a dir? */
+        goto junk;
+
       g_mutex_lock (&dconf_engine_global_lock);
       engines = g_slist_copy_deep (dconf_engine_global_list, (GCopyFunc) dconf_engine_ref, NULL);
       g_mutex_unlock (&dconf_engine_global_lock);
@@ -1242,6 +1273,7 @@ dconf_engine_handle_dbus_signal (GBusType     type,
           dconf_engine_unref (engine);
         }
 
+junk:
       g_free (changes);
     }
 
@@ -1256,6 +1288,10 @@ dconf_engine_handle_dbus_signal (GBusType     type,
 
       g_variant_get (body, "(&s)", &path);
 
+      /* Rejecting junk here is relatively straightforward */
+      if (!dconf_is_path (path, NULL))
+        return;
+
       g_mutex_lock (&dconf_engine_global_lock);
       engines = g_slist_copy_deep (dconf_engine_global_list, (GCopyFunc) dconf_engine_ref, NULL);
       g_mutex_unlock (&dconf_engine_global_lock);


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