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
This commit is contained in:
Olivier Fourdan 2020-08-12 19:30:04 +02:00 committed by Robert Mader
parent e44c42f254
commit 5171e35a97
4 changed files with 108 additions and 14 deletions

View File

@ -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>

View File

@ -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 */

View File

@ -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

View File

@ -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)
{