[mutter] xwayland: Add a setting to disable selected X extensions



commit 5171e35a9706202ec17f0490762d12f2423c2724
Author: Olivier Fourdan <ofourdan redhat com>
Date:   Wed Aug 12 19:30:04 2020 +0200

    xwayland: Add a setting to disable selected X extensions
    
    The X server, including Xwayland, can be compiled with different X11
    extensions enabled at build time.
    
    When an X11 extension is built in the X server, it's usually also
    enabled at run time. Users can chose to disable those extensions at run
    time using the X server command line option "-extension".
    
    However, in the case of Xwayland, it is spawned automatically by the
    Wayland compositor, and the command line options are not configurable
    by users.
    
    Add a new setting to disable a selected set of X extension in Xwayland
    at startup, without needing to rebuild Xwayland.
    
    Of course, if Xwayland is not built with a given extension support in
    the first place (which is the default for the security extension for
    example), that option has no effect.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1405

 data/org.gnome.mutter.wayland.gschema.xml.in | 21 ++++++++
 src/backends/meta-settings-private.h         |  8 ++++
 src/backends/meta-settings.c                 | 22 +++++++++
 src/wayland/meta-xwayland.c                  | 71 ++++++++++++++++++++++------
 4 files changed, 108 insertions(+), 14 deletions(-)
---
diff --git a/data/org.gnome.mutter.wayland.gschema.xml.in b/data/org.gnome.mutter.wayland.gschema.xml.in
index 23ce8386c6..b8674b3acd 100644
--- a/data/org.gnome.mutter.wayland.gschema.xml.in
+++ b/data/org.gnome.mutter.wayland.gschema.xml.in
@@ -1,4 +1,10 @@
 <schemalist>
+
+  <flags id="org.gnome.mutter.MetaXwaylandDisableExtension">
+    <value nick="Security" value="1"/>
+    <value nick="Xtest" value="2"/>
+  </flags>
+
   <schema id="org.gnome.mutter.wayland.keybindings" path="/org/gnome/mutter/wayland/keybindings/"
          gettext-domain="@GETTEXT_DOMAIN@">
     <key name="switch-to-session-1" type="as">
@@ -104,6 +110,21 @@
       </description>
     </key>
 
+    <key name="xwayland-disable-extension"
+        flags='org.gnome.mutter.MetaXwaylandDisableExtension'>
+      <default>["Security"]</default>
+      <summary>Disable selected X extensions in Xwayland</summary>
+      <description>
+        This option disables the selected X extensions in Xwayland if
+        Xwayland was built with support for those X extensions.
+
+        This option has no effect if Xwayland was built without support
+        for the selected extensions.
+
+        Xwayland needs to be restarted for this setting to take effect.
+      </description>
+    </key>
+
   </schema>
 
 </schemalist>
diff --git a/src/backends/meta-settings-private.h b/src/backends/meta-settings-private.h
index 5e5d8e8dd8..91b3eb17a7 100644
--- a/src/backends/meta-settings-private.h
+++ b/src/backends/meta-settings-private.h
@@ -37,6 +37,12 @@ typedef enum _MetaExperimentalFeature
   META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND  = (1 << 3),
 } MetaExperimentalFeature;
 
+typedef enum _MetaXwaylandExtension
+{
+  META_XWAYLAND_EXTENSION_SECURITY = (1 << 0),
+  META_XWAYLAND_EXTENSION_XTEST = (1 << 1),
+} MetaXwaylandExtension;
+
 #define META_TYPE_SETTINGS (meta_settings_get_type ())
 G_DECLARE_FINAL_TYPE (MetaSettings, meta_settings,
                       META, SETTINGS, GObject)
@@ -69,4 +75,6 @@ void meta_settings_get_xwayland_grab_patterns (MetaSettings  *settings,
 
 gboolean meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings);
 
+int meta_settings_get_xwayland_disable_extensions (MetaSettings *settings);
+
 #endif /* META_SETTINGS_PRIVATE_H */
diff --git a/src/backends/meta-settings.c b/src/backends/meta-settings.c
index 14a9ead225..f14dbfae61 100644
--- a/src/backends/meta-settings.c
+++ b/src/backends/meta-settings.c
@@ -68,6 +68,9 @@ struct _MetaSettings
   gboolean xwayland_allow_grabs;
   GPtrArray *xwayland_grab_allow_list_patterns;
   GPtrArray *xwayland_grab_deny_list_patterns;
+
+  /* A bitmask of MetaXwaylandExtension enum */
+  int xwayland_disable_extensions;
 };
 
 G_DEFINE_TYPE (MetaSettings, meta_settings, G_TYPE_OBJECT)
@@ -387,6 +390,14 @@ update_xwayland_allow_grabs (MetaSettings *settings)
                             "xwayland-allow-grabs");
 }
 
+static void
+update_xwayland_disable_extensions (MetaSettings *settings)
+{
+  settings->xwayland_disable_extensions =
+    g_settings_get_flags (settings->wayland_settings,
+                          "xwayland-disable-extension");
+}
+
 static void
 wayland_settings_changed (GSettings    *wayland_settings,
                           gchar        *key,
@@ -401,6 +412,10 @@ wayland_settings_changed (GSettings    *wayland_settings,
     {
       update_xwayland_grab_access_rules (settings);
     }
+  else if (g_str_equal (key, "xwayland-disable-extension"))
+    {
+      update_xwayland_disable_extensions (settings);
+    }
 }
 
 void
@@ -418,6 +433,12 @@ meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings)
   return (settings->xwayland_allow_grabs);
 }
 
+int
+meta_settings_get_xwayland_disable_extensions (MetaSettings *settings)
+{
+  return (settings->xwayland_disable_extensions);
+}
+
 MetaSettings *
 meta_settings_new (MetaBackend *backend)
 {
@@ -471,6 +492,7 @@ meta_settings_init (MetaSettings *settings)
   update_experimental_features (settings);
   update_xwayland_grab_access_rules (settings);
   update_xwayland_allow_grabs (settings);
+  update_xwayland_disable_extensions (settings);
 }
 
 static void
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 1b67c0a926..4a9d07ea99 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -39,8 +39,10 @@
 #include <unistd.h>
 #include <X11/Xauth.h>
 
+#include "backends/meta-settings-private.h"
 #include "core/main-private.h"
 #include "meta/main.h"
+#include "meta/meta-backend.h"
 #include "wayland/meta-xwayland-surface.h"
 #include "x11/meta-x11-display-private.h"
 
@@ -574,12 +576,25 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager,
                              GAsyncReadyCallback  callback,
                              gpointer             user_data)
 {
+  struct {
+    const char *extension_name;
+    MetaXwaylandExtension disable_extension;
+  } x11_extension_names[] = {
+    { "SECURITY", META_XWAYLAND_EXTENSION_SECURITY },
+    { "XTEST", META_XWAYLAND_EXTENSION_XTEST },
+  };
+
   int xwayland_client_fd[2];
   int displayfd[2];
   g_autoptr(GSubprocessLauncher) launcher = NULL;
   GSubprocessFlags flags;
   GError *error = NULL;
   g_autoptr (GTask) task = NULL;
+  MetaBackend *backend;
+  MetaSettings *settings;
+  const char *args[32];
+  int xwayland_disable_extensions;
+  int i, j;
 
   task = g_task_new (NULL, cancellable, callback, user_data);
   g_task_set_source_tag (task, meta_xwayland_start_xserver);
@@ -614,6 +629,11 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager,
       flags |= G_SUBPROCESS_FLAGS_STDERR_SILENCE;
     }
 
+  backend = meta_get_backend ();
+  settings = meta_backend_get_settings (backend);
+  xwayland_disable_extensions =
+    meta_settings_get_xwayland_disable_extensions (settings);
+
   launcher = g_subprocess_launcher_new (flags);
 
   g_subprocess_launcher_take_fd (launcher, xwayland_client_fd[1], 3);
@@ -624,23 +644,46 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager,
 
   g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
 
-  manager->proc = g_subprocess_launcher_spawn (launcher, &error,
-                                               XWAYLAND_PATH,
-                                               manager->public_connection.name,
-                                               "-rootless",
-                                               "-noreset",
-                                               "-accessx",
-                                               "-core",
-                                               "-auth", manager->auth_file,
-                                               "-listen", "4",
-                                               "-listen", "5",
-                                               "-displayfd", "6",
+  i = 0;
+  args[i++] = XWAYLAND_PATH;
+  args[i++] = manager->public_connection.name;
+  args[i++] = "-rootless";
+  args[i++] = "-noreset";
+  args[i++] = "-accessx";
+  args[i++] = "-core";
+  args[i++] = "-auth";
+  args[i++] = manager->auth_file;
+  args[i++] = "-listen";
+  args[i++] = "4";
+  args[i++] = "-listen";
+  args[i++] = "5";
+  args[i++] = "-displayfd";
+  args[i++] = "6",
 #ifdef HAVE_XWAYLAND_INITFD
-                                               "-initfd", "7",
+  args[i++] = "-initfd";
+  args[i++] = "7";
 #else
-                                               "-listen", "7",
+  args[i++] = "-listen";
+  args[i++] = "7";
 #endif
-                                               NULL);
+  for (j = 0; j <  G_N_ELEMENTS (x11_extension_names); j++)
+    {
+      /* Make sure we don't go past the array size - We need room for
+       * 2 arguments, plus the last NULL terminator.
+       */
+      if (i + 3 > G_N_ELEMENTS (args))
+        break;
+
+      if (xwayland_disable_extensions & x11_extension_names[j].disable_extension)
+        {
+          args[i++] = "-extension";
+          args[i++] = x11_extension_names[j].extension_name;
+        }
+  }
+  /* Terminator */
+  args[i++] = NULL;
+
+  manager->proc = g_subprocess_launcher_spawnv (launcher, args, &error);
 
   if (!manager->proc)
     {


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