summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2013-11-27 14:00:21 -0500
committerRyan Lortie <desrt@desrt.ca>2013-11-27 14:02:22 -0500
commit0a8e738d62fc99466b39f4f25d4c9e343fe8199c (patch)
tree34bd8531037b46e8bc4358581d06721b0ff52790
parent19a05190e91de94af913075beb67725b86814231 (diff)
downloaddconf-0a8e738d62fc99466b39f4f25d4c9e343fe8199c.tar.gz
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.
-rw-r--r--engine/dconf-engine.c36
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);