7e481fa
From eaabecd70f79c89f6bfd912557c0cbb7718d4c63 Mon Sep 17 00:00:00 2001
7e481fa
From: Ray Strode <rstrode@redhat.com>
7e481fa
Date: Mon, 5 Nov 2012 17:07:05 -0500
7e481fa
Subject: [PATCH] daemon: allow NULs in X11 cookie
7e481fa
7e481fa
We currently allow the slave access to its X server via two
7e481fa
mechanisms:
7e481fa
7e481fa
1) we set XAUTHORITY to point to the X servers Xauthority file
7e481fa
2) we call XSetAuthorization with the cookie from the Xauthority file
7e481fa
7e481fa
1) may fail if the user's hostname changes at the wrong moment, and
7e481fa
a bug in the code meant that 2 would fail if NULs are encoded in the
7e481fa
auth cookie.
7e481fa
7e481fa
This commit fixes 2) to work with embedded NUL bytes.
7e481fa
7e481fa
https://bugzilla.gnome.org/show_bug.cgi?id=687691
7e481fa
---
7e481fa
 daemon/gdm-display.c   |  7 ++++++-
7e481fa
 daemon/gdm-display.xml |  4 +++-
7e481fa
 daemon/gdm-slave.c     | 38 ++++++++++++++++++++++++++++----------
7e481fa
 3 files changed, 37 insertions(+), 12 deletions(-)
7e481fa
7e481fa
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
7e481fa
index 42f5990..435dc1c 100644
7e481fa
--- a/daemon/gdm-display.c
7e481fa
+++ b/daemon/gdm-display.c
7e481fa
@@ -1106,10 +1106,15 @@ handle_get_x11_cookie (GdmDBusDisplay        *skeleton,
7e481fa
                        GdmDisplay            *display)
7e481fa
 {
7e481fa
         GArray *cookie = NULL;
7e481fa
+        GVariant *variant;
7e481fa
 
7e481fa
         gdm_display_get_x11_cookie (display, &cookie, NULL);
7e481fa
 
7e481fa
-        gdm_dbus_display_complete_get_x11_cookie (skeleton, invocation, cookie->data);
7e481fa
+        variant = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
7e481fa
+                                             cookie->data,
7e481fa
+                                             cookie->len,
7e481fa
+                                             sizeof (char));
7e481fa
+        gdm_dbus_display_complete_get_x11_cookie (skeleton, invocation, variant);
7e481fa
 
7e481fa
         g_array_unref (cookie);
7e481fa
         return TRUE;
7e481fa
diff --git a/daemon/gdm-display.xml b/daemon/gdm-display.xml
7e481fa
index 904e0ae..48d03db 100644
7e481fa
--- a/daemon/gdm-display.xml
7e481fa
+++ b/daemon/gdm-display.xml
7e481fa
@@ -11,7 +11,9 @@
7e481fa
       <arg name="name" direction="out" type="i"/>
7e481fa
     </method>
7e481fa
     <method name="GetX11Cookie">
7e481fa
-      <arg name="x11_cookie" direction="out" type="ay"/>
7e481fa
+      <arg name="x11_cookie" direction="out" type="ay">
7e481fa
+        <annotation name="org.gtk.GDBus.C.ForceGVariant" value="true"/>
7e481fa
+      </arg>
7e481fa
     </method>
7e481fa
     <method name="GetX11AuthorityFile">
7e481fa
       <arg name="filename" direction="out" type="s"/>
7e481fa
diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c
7e481fa
index 948406a..15df03a 100644
7e481fa
--- a/daemon/gdm-slave.c
7e481fa
+++ b/daemon/gdm-slave.c
7e481fa
@@ -98,7 +98,7 @@ struct GdmSlavePrivate
7e481fa
         char            *parent_display_name;
7e481fa
         char            *parent_display_x11_authority_file;
7e481fa
         char            *windowpath;
7e481fa
-        char            *display_x11_cookie;
7e481fa
+        GBytes          *display_x11_cookie;
7e481fa
         gboolean         display_is_initial;
7e481fa
 
7e481fa
         GdmDBusDisplay  *display_proxy;
7e481fa
@@ -665,10 +665,13 @@ gdm_slave_connect_to_x11_display (GdmSlave *slave)
7e481fa
         sigprocmask (SIG_BLOCK, &mask, &omask);
7e481fa
 
7e481fa
         /* Give slave access to the display independent of current hostname */
7e481fa
-        XSetAuthorization ("MIT-MAGIC-COOKIE-1",
7e481fa
-                           strlen ("MIT-MAGIC-COOKIE-1"),
7e481fa
-                           slave->priv->display_x11_cookie,
7e481fa
-                           strlen (slave->priv->display_x11_cookie));
7e481fa
+        if (slave->priv->display_x11_cookie != NULL) {
7e481fa
+                XSetAuthorization ("MIT-MAGIC-COOKIE-1",
7e481fa
+                                   strlen ("MIT-MAGIC-COOKIE-1"),
7e481fa
+                                   (gpointer)
7e481fa
+                                   g_bytes_get_data (slave->priv->display_x11_cookie, NULL),
7e481fa
+                                   g_bytes_get_size (slave->priv->display_x11_cookie));
7e481fa
+        }
7e481fa
 
7e481fa
         slave->priv->server_display = XOpenDisplay (slave->priv->display_name);
7e481fa
 
7e481fa
@@ -736,9 +739,12 @@ gdm_slave_set_slave_bus_name (GdmSlave *slave)
7e481fa
 static gboolean
7e481fa
 gdm_slave_real_start (GdmSlave *slave)
7e481fa
 {
7e481fa
-        gboolean res;
7e481fa
-        char    *id;
7e481fa
-        GError  *error;
7e481fa
+        gboolean    res;
7e481fa
+        char       *id;
7e481fa
+        GError     *error;
7e481fa
+        GVariant   *x11_cookie;
7e481fa
+        const char *x11_cookie_bytes;
7e481fa
+        gsize       x11_cookie_size;
7e481fa
 
7e481fa
         g_debug ("GdmSlave: Starting slave");
7e481fa
 
7e481fa
@@ -826,7 +832,7 @@ gdm_slave_real_start (GdmSlave *slave)
7e481fa
 
7e481fa
         error = NULL;
7e481fa
         res = gdm_dbus_display_call_get_x11_cookie_sync (slave->priv->display_proxy,
7e481fa
-                                                         &slave->priv->display_x11_cookie,
7e481fa
+                                                         &x11_cookie,
7e481fa
                                                          NULL,
7e481fa
                                                          &error);
7e481fa
         if (! res) {
7e481fa
@@ -835,6 +841,18 @@ gdm_slave_real_start (GdmSlave *slave)
7e481fa
                 return FALSE;
7e481fa
         }
7e481fa
 
7e481fa
+        x11_cookie_bytes = g_variant_get_fixed_array (x11_cookie,
7e481fa
+                                                      &x11_cookie_size,
7e481fa
+                                                      sizeof (char));
7e481fa
+
7e481fa
+        if (x11_cookie_bytes != NULL && x11_cookie_size > 0) {
7e481fa
+                g_bytes_unref (slave->priv->display_x11_cookie);
7e481fa
+                slave->priv->display_x11_cookie = g_bytes_new (x11_cookie_bytes,
7e481fa
+                                                               x11_cookie_size);
7e481fa
+        }
7e481fa
+
7e481fa
+        g_variant_unref (x11_cookie);
7e481fa
+
7e481fa
         error = NULL;
7e481fa
         res = gdm_dbus_display_call_get_x11_authority_file_sync (slave->priv->display_proxy,
7e481fa
                                                                  &slave->priv->display_x11_authority_file,
7e481fa
@@ -2175,7 +2193,7 @@ gdm_slave_finalize (GObject *object)
7e481fa
         g_free (slave->priv->parent_display_name);
7e481fa
         g_free (slave->priv->parent_display_x11_authority_file);
7e481fa
         g_free (slave->priv->windowpath);
7e481fa
-        g_free (slave->priv->display_x11_cookie);
7e481fa
+        g_bytes_unref (slave->priv->display_x11_cookie);
7e481fa
 
7e481fa
         G_OBJECT_CLASS (gdm_slave_parent_class)->finalize (object);
7e481fa
 }
7e481fa
-- 
7e481fa
1.7.12.1
7e481fa