[mutter/wip/carlosg/xwayland-startup-side-channel: 24/26] wayland: Set up initialization X11 socket



commit 19292d30133cafeae34e497e15d9ebd3416fc3fc
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Jul 19 22:50:31 2019 +0200

    wayland: Set up initialization X11 socket
    
    This is used by GDK and the X11 bits, but may also be used for
    other initialization services we might need to run along with
    Xwayland initialization.
    
    However, as the -initfd argument in Xwayland is a fairly new
    feature, add some meson build-time checks so that the feature
    is handled transparently while allowing to explicitly set/unset
    it.

 config.h.meson                     |  3 ++
 meson.build                        | 15 +++++++
 meson_options.txt                  |  6 +++
 src/wayland/meta-wayland-private.h |  9 ++++-
 src/wayland/meta-wayland.c         |  4 +-
 src/wayland/meta-xwayland.c        | 80 +++++++++++++++++++++++++++-----------
 6 files changed, 92 insertions(+), 25 deletions(-)
---
diff --git a/config.h.meson b/config.h.meson
index 0bab71848..0edff4d57 100644
--- a/config.h.meson
+++ b/config.h.meson
@@ -67,3 +67,6 @@
 /* Either <sys/random.h> or <linux/random.h> */
 #mesondefine HAVE_SYS_RANDOM
 #mesondefine HAVE_LINUX_RANDOM
+
+/* Whether Xwayland has -initfd option */
+#mesondefine HAVE_XWAYLAND_INITFD
diff --git a/meson.build b/meson.build
index f6395054f..3b78e190c 100644
--- a/meson.build
+++ b/meson.build
@@ -372,6 +372,7 @@ if cc.has_header_symbol('sys/prctl.h', 'prctl')
   cdata.set('HAVE_SYS_PRCTL', 1)
 endif
 
+have_xwayland_initfd = false
 if have_wayland
   xwayland_path = get_option('xwayland_path')
   if xwayland_path == ''
@@ -387,6 +388,19 @@ if have_wayland
   else
     error('Required function getrandom not found')
   endif
+
+  # For Xwayland -initfd usage
+  use_initfd = get_option('xwayland_initfd')
+  if use_initfd.auto()
+    xwayland_options = run_command(xwayland_path, '-help')
+    have_xwayland_initfd = xwayland_options.stderr().contains('-initfd')
+  else
+    have_xwayland_initfd = use_initfd.enabled()
+  endif
+
+  if (have_xwayland_initfd)
+    cdata.set('HAVE_XWAYLAND_INITFD', 1)
+  endif
 endif
 
 xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules')
@@ -445,6 +459,7 @@ output = [
   '        Startup notification..... ' + have_startup_notification.to_string(),
   '        Introspection............ ' + have_introspection.to_string(),
   '        Profiler................. ' + have_profiler.to_string(),
+  '        Xwayland initfd.......... ' + have_xwayland_initfd.to_string(),
   '',
   '    Tests:',
   '',
diff --git a/meson_options.txt b/meson_options.txt
index 73aa7adde..097809a93 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -152,3 +152,9 @@ option('xwayland_grab_default_access_rules',
   value: 'gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr',
   description: 'Comma delimited list of applications ressources or class allowed to issue X11 grabs in 
Xwayland'
 )
+
+option('xwayland_initfd',
+  type: 'feature',
+  value: 'auto',
+  description: 'Whether Xwayland -initfd argument is used'
+)
diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h
index aa8e4deab..e28ca06d6 100644
--- a/src/wayland/meta-wayland-private.h
+++ b/src/wayland/meta-wayland-private.h
@@ -48,11 +48,18 @@ typedef struct
   char *lock_file;
   int abstract_fd;
   int unix_fd;
+  char *name;
+} MetaXWaylandConnection;
+
+typedef struct
+{
+  MetaXWaylandConnection private_connection;
+  MetaXWaylandConnection public_connection;
+
   guint xserver_grace_period_id;
   struct wl_display *wayland_display;
   struct wl_client *client;
   struct wl_resource *xserver_resource;
-  char *display_name;
   char *auth_file;
 
   GCancellable *xserver_died_cancellable;
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index 806c897c9..da19ec955 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -445,7 +445,7 @@ meta_wayland_init (void)
 
   if (meta_get_x11_display_policy () != META_DISPLAY_POLICY_DISABLED)
     {
-      set_gnome_env ("DISPLAY", meta_wayland_get_xwayland_display_name (compositor));
+      set_gnome_env ("DISPLAY", compositor->xwayland_manager.public_connection.name);
       set_gnome_env ("XAUTHORITY", meta_wayland_get_xwayland_auth_file (compositor));
     }
 
@@ -461,7 +461,7 @@ meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor)
 const char *
 meta_wayland_get_xwayland_display_name (MetaWaylandCompositor *compositor)
 {
-  return compositor->xwayland_manager.display_name;
+  return compositor->xwayland_manager.private_connection.name;
 }
 
 void
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 7c419adba..6705609f8 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -362,6 +362,7 @@ xserver_died (GObject      *source,
               gpointer      user_data)
 {
   GSubprocess *proc = G_SUBPROCESS (source);
+  MetaDisplay *display = meta_get_display ();
   g_autoptr (GError) error = NULL;
 
   if (!g_subprocess_wait_finish (proc, result, &error))
@@ -386,7 +387,6 @@ xserver_died (GObject      *source,
   else if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND)
     {
       MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
-      MetaDisplay *display = meta_get_display ();
 
       if (display->x11_display)
         meta_display_shutdown_x11 (display);
@@ -429,6 +429,8 @@ meta_xwayland_override_display_number (int number)
 static gboolean
 open_display_sockets (MetaXWaylandManager *manager,
                       int                  display_index,
+                      int                 *abstract_fd_out,
+                      int                 *unix_fd_out,
                       gboolean            *fatal)
 {
   int abstract_fd, unix_fd;
@@ -446,14 +448,15 @@ open_display_sockets (MetaXWaylandManager *manager,
       return FALSE;
     }
 
-  manager->abstract_fd = abstract_fd;
-  manager->unix_fd = unix_fd;
+  *abstract_fd_out = abstract_fd;
+  *unix_fd_out = unix_fd;
 
   return TRUE;
 }
 
 static gboolean
-choose_xdisplay (MetaXWaylandManager *manager)
+choose_xdisplay (MetaXWaylandManager    *manager,
+                 MetaXWaylandConnection *connection)
 {
   int display = 0;
   char *lock_file = NULL;
@@ -473,7 +476,10 @@ choose_xdisplay (MetaXWaylandManager *manager)
           return FALSE;
         }
 
-      if (!open_display_sockets (manager, display, &fatal))
+      if (!open_display_sockets (manager, display,
+                                 &connection->abstract_fd,
+                                 &connection->unix_fd,
+                                 &fatal))
         {
           unlink (lock_file);
 
@@ -493,9 +499,9 @@ choose_xdisplay (MetaXWaylandManager *manager)
     }
   while (1);
 
-  manager->display_index = display;
-  manager->display_name = g_strdup_printf (":%d", manager->display_index);
-  manager->lock_file = lock_file;
+  connection->display_index = display;
+  connection->name = g_strdup_printf (":%d", connection->display_index);
+  connection->lock_file = lock_file;
 
   return TRUE;
 }
@@ -659,14 +665,16 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager,
   launcher = g_subprocess_launcher_new (flags);
 
   g_subprocess_launcher_take_fd (launcher, xwayland_client_fd[1], 3);
-  g_subprocess_launcher_take_fd (launcher, manager->abstract_fd, 4);
-  g_subprocess_launcher_take_fd (launcher, manager->unix_fd, 5);
+  g_subprocess_launcher_take_fd (launcher, manager->public_connection.abstract_fd, 4);
+  g_subprocess_launcher_take_fd (launcher, manager->public_connection.unix_fd, 5);
   g_subprocess_launcher_take_fd (launcher, displayfd[1], 6);
+  g_subprocess_launcher_take_fd (launcher, manager->private_connection.abstract_fd, 7);
 
   g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
 
   manager->proc = g_subprocess_launcher_spawn (launcher, &error,
-                                               XWAYLAND_PATH, manager->display_name,
+                                               XWAYLAND_PATH,
+                                               manager->public_connection.name,
                                                "-rootless",
                                                "-noreset",
                                                "-accessx",
@@ -675,7 +683,13 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager,
                                                "-listen", "4",
                                                "-listen", "5",
                                                "-displayfd", "6",
+#ifdef HAVE_XWAYLAND_INITFD
+                                               "-initfd", "7",
+#else
+                                               "-listen", "7",
+#endif
                                                NULL);
+
   if (!manager->proc)
     {
       g_task_return_error (task, error);
@@ -783,9 +797,11 @@ meta_xwayland_init (MetaXWaylandManager *manager,
   MetaDisplayPolicy policy;
   gboolean fatal;
 
-  if (!manager->display_name)
+  if (!manager->public_connection.name)
     {
-      if (!choose_xdisplay (manager))
+      if (!choose_xdisplay (manager, &manager->public_connection))
+        return FALSE;
+      if (!choose_xdisplay (manager, &manager->private_connection))
         return FALSE;
 
       if (!prepare_auth_file (manager))
@@ -793,7 +809,18 @@ meta_xwayland_init (MetaXWaylandManager *manager,
     }
   else
     {
-      if (!open_display_sockets (manager, manager->display_index, &fatal))
+      if (!open_display_sockets (manager,
+                                 manager->public_connection.display_index,
+                                 &manager->public_connection.abstract_fd,
+                                 &manager->public_connection.unix_fd,
+                                 &fatal))
+        return FALSE;
+
+      if (!open_display_sockets (manager,
+                                 manager->private_connection.display_index,
+                                 &manager->private_connection.abstract_fd,
+                                 &manager->private_connection.unix_fd,
+                                 &fatal))
         return FALSE;
     }
 
@@ -802,7 +829,7 @@ meta_xwayland_init (MetaXWaylandManager *manager,
 
   if (policy == META_DISPLAY_POLICY_ON_DEMAND)
     {
-      g_unix_fd_add (manager->abstract_fd, G_IO_IN,
+      g_unix_fd_add (manager->public_connection.abstract_fd, G_IO_IN,
                      xdisplay_connection_activity_cb, manager);
     }
 
@@ -855,20 +882,29 @@ meta_xwayland_shutdown (MetaXWaylandManager *manager)
 
   g_cancellable_cancel (manager->xserver_died_cancellable);
 
-  snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->display_index);
+  snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->public_connection.display_index);
+  unlink (path);
+
+  snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->private_connection.display_index);
   unlink (path);
 
-  g_clear_pointer (&manager->display_name, g_free);
+  g_clear_pointer (&manager->public_connection.name, g_free);
+  g_clear_pointer (&manager->private_connection.name, g_free);
+  if (manager->public_connection.lock_file)
+    {
+      unlink (manager->public_connection.lock_file);
+      g_clear_pointer (&manager->public_connection.lock_file, g_free);
+    }
+  if (manager->private_connection.lock_file)
+    {
+      unlink (manager->private_connection.lock_file);
+      g_clear_pointer (&manager->private_connection.lock_file, g_free);
+    }
   if (manager->auth_file)
     {
       unlink (manager->auth_file);
       g_clear_pointer (&manager->auth_file, g_free);
     }
-  if (manager->lock_file)
-    {
-      unlink (manager->lock_file);
-      g_clear_pointer (&manager->lock_file, g_free);
-    }
 }
 
 static void


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