Fixes a race in wl_seat capabilities
Resolves: rhbz#2003032
This commit is contained in:
parent
be00783f06
commit
616b5baadf
192
0001-wayland-Avoid-a-race-in-wl_seat-capabilities.patch
Normal file
192
0001-wayland-Avoid-a-race-in-wl_seat-capabilities.patch
Normal file
@ -0,0 +1,192 @@
|
||||
From 5e4a1290ce75ed94e3f0f457d35a225f2ef3878c Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Tue, 28 Nov 2017 10:54:08 +0100
|
||||
Subject: [PATCH] wayland: Avoid a race in wl_seat capabilities
|
||||
|
||||
The way wl_seat capabilities work, by notifying clients of capabilities
|
||||
changes, and clients consequently requesting the relevant interface
|
||||
objects (pointer, keyboard, touch) is inherently racy.
|
||||
|
||||
On quick VT changes for example, capabilities on the seat will be added
|
||||
and removed, and by the time the client receives the capability change
|
||||
notification and requests the relevant keyboard, pointer or touch,
|
||||
another VT switch might have occurred and the wl_pointer, wl_keyboard or
|
||||
wl_touch already destroyed, leading to a protocol error which kills the
|
||||
client.
|
||||
|
||||
To avoid this, create the objects when requested regardless of the
|
||||
capabilities.
|
||||
|
||||
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1797
|
||||
Related: https://bugzilla.gnome.org/show_bug.cgi?id=790932
|
||||
---
|
||||
src/wayland/meta-wayland-pointer.c | 45 ++++++++++++++++++++++++------
|
||||
src/wayland/meta-wayland-seat.c | 9 ++----
|
||||
src/wayland/meta-wayland-touch.c | 8 ------
|
||||
3 files changed, 40 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
|
||||
index 3132abfd2..abd779ad7 100644
|
||||
--- a/src/wayland/meta-wayland-pointer.c
|
||||
+++ b/src/wayland/meta-wayland-pointer.c
|
||||
@@ -109,7 +109,7 @@ meta_wayland_pointer_client_new (void)
|
||||
}
|
||||
|
||||
static void
|
||||
-meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client)
|
||||
+meta_wayland_pointer_make_resources_inert (MetaWaylandPointerClient *pointer_client)
|
||||
{
|
||||
struct wl_resource *resource, *next;
|
||||
|
||||
@@ -141,10 +141,25 @@ meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client)
|
||||
wl_list_init (wl_resource_get_link (resource));
|
||||
wl_resource_set_user_data (resource, NULL);
|
||||
}
|
||||
+}
|
||||
|
||||
+static void
|
||||
+meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client)
|
||||
+{
|
||||
+ meta_wayland_pointer_make_resources_inert (pointer_client);
|
||||
g_free (pointer_client);
|
||||
}
|
||||
|
||||
+static void
|
||||
+make_resources_inert_foreach (gpointer key,
|
||||
+ gpointer value,
|
||||
+ gpointer data)
|
||||
+{
|
||||
+ MetaWaylandPointerClient *pointer_client = value;
|
||||
+
|
||||
+ meta_wayland_pointer_make_resources_inert (pointer_client);
|
||||
+}
|
||||
+
|
||||
static gboolean
|
||||
meta_wayland_pointer_client_is_empty (MetaWaylandPointerClient *pointer_client)
|
||||
{
|
||||
@@ -158,8 +173,6 @@ MetaWaylandPointerClient *
|
||||
meta_wayland_pointer_get_pointer_client (MetaWaylandPointer *pointer,
|
||||
struct wl_client *client)
|
||||
{
|
||||
- if (!pointer->pointer_clients)
|
||||
- return NULL;
|
||||
return g_hash_table_lookup (pointer->pointer_clients, client);
|
||||
}
|
||||
|
||||
@@ -475,10 +488,6 @@ meta_wayland_pointer_enable (MetaWaylandPointer *pointer)
|
||||
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||
ClutterSeat *clutter_seat;
|
||||
|
||||
- pointer->pointer_clients =
|
||||
- g_hash_table_new_full (NULL, NULL, NULL,
|
||||
- (GDestroyNotify) meta_wayland_pointer_client_free);
|
||||
-
|
||||
pointer->cursor_surface = NULL;
|
||||
|
||||
clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
@@ -508,6 +517,10 @@ meta_wayland_pointer_disable (MetaWaylandPointer *pointer)
|
||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||
ClutterSeat *clutter_seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
|
||||
+ g_hash_table_foreach (pointer->pointer_clients,
|
||||
+ make_resources_inert_foreach,
|
||||
+ NULL);
|
||||
+
|
||||
g_signal_handlers_disconnect_by_func (cursor_tracker,
|
||||
(gpointer) meta_wayland_pointer_on_cursor_changed,
|
||||
pointer);
|
||||
@@ -531,7 +544,6 @@ meta_wayland_pointer_disable (MetaWaylandPointer *pointer)
|
||||
meta_wayland_pointer_set_focus (pointer, NULL);
|
||||
meta_wayland_pointer_set_current (pointer, NULL);
|
||||
|
||||
- g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref);
|
||||
pointer->cursor_surface = NULL;
|
||||
}
|
||||
|
||||
@@ -1356,11 +1368,28 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer)
|
||||
pointer->default_grab.interface = &default_pointer_grab_interface;
|
||||
pointer->default_grab.pointer = pointer;
|
||||
pointer->grab = &pointer->default_grab;
|
||||
+ pointer->pointer_clients =
|
||||
+ g_hash_table_new_full (NULL, NULL, NULL,
|
||||
+ (GDestroyNotify) meta_wayland_pointer_client_free);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+meta_wayland_pointer_finalize (GObject *object)
|
||||
+{
|
||||
+ MetaWaylandPointer *pointer = META_WAYLAND_POINTER (object);
|
||||
+
|
||||
+ g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref);
|
||||
+
|
||||
+ G_OBJECT_CLASS (meta_wayland_pointer_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_pointer_class_init (MetaWaylandPointerClass *klass)
|
||||
{
|
||||
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
+
|
||||
+ object_class->finalize = meta_wayland_pointer_finalize;
|
||||
+
|
||||
signals[FOCUS_SURFACE_CHANGED] = g_signal_new ("focus-surface-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
|
||||
index c6390dde7..efce6d6d6 100644
|
||||
--- a/src/wayland/meta-wayland-seat.c
|
||||
+++ b/src/wayland/meta-wayland-seat.c
|
||||
@@ -46,8 +46,7 @@ seat_get_pointer (struct wl_client *client,
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
|
||||
MetaWaylandPointer *pointer = seat->pointer;
|
||||
|
||||
- if (meta_wayland_seat_has_pointer (seat))
|
||||
- meta_wayland_pointer_create_new_resource (pointer, client, resource, id);
|
||||
+ meta_wayland_pointer_create_new_resource (pointer, client, resource, id);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -58,8 +57,7 @@ seat_get_keyboard (struct wl_client *client,
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
|
||||
MetaWaylandKeyboard *keyboard = seat->keyboard;
|
||||
|
||||
- if (meta_wayland_seat_has_keyboard (seat))
|
||||
- meta_wayland_keyboard_create_new_resource (keyboard, client, resource, id);
|
||||
+ meta_wayland_keyboard_create_new_resource (keyboard, client, resource, id);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -70,8 +68,7 @@ seat_get_touch (struct wl_client *client,
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
|
||||
MetaWaylandTouch *touch = seat->touch;
|
||||
|
||||
- if (meta_wayland_seat_has_touch (seat))
|
||||
- meta_wayland_touch_create_new_resource (touch, client, resource, id);
|
||||
+ meta_wayland_touch_create_new_resource (touch, client, resource, id);
|
||||
}
|
||||
|
||||
static void
|
||||
diff --git a/src/wayland/meta-wayland-touch.c b/src/wayland/meta-wayland-touch.c
|
||||
index 002ff16f7..15f0312eb 100644
|
||||
--- a/src/wayland/meta-wayland-touch.c
|
||||
+++ b/src/wayland/meta-wayland-touch.c
|
||||
@@ -521,16 +521,8 @@ meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch,
|
||||
struct wl_resource *seat_resource,
|
||||
uint32_t id)
|
||||
{
|
||||
- MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||
struct wl_resource *cr;
|
||||
|
||||
- if (!meta_wayland_seat_has_touch (seat))
|
||||
- {
|
||||
- wl_resource_post_error (seat_resource, WL_DISPLAY_ERROR_INVALID_METHOD,
|
||||
- "Cannot retrieve touch interface without touch capability");
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
cr = wl_resource_create (client, &wl_touch_interface, wl_resource_get_version (seat_resource), id);
|
||||
wl_resource_set_implementation (cr, &touch_interface, touch, unbind_resource);
|
||||
wl_list_insert (&touch->resource_list, wl_resource_get_link (cr));
|
||||
--
|
||||
2.31.1
|
||||
|
10
mutter.spec
10
mutter.spec
@ -10,7 +10,7 @@
|
||||
|
||||
Name: mutter
|
||||
Version: 40.4
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
Summary: Window and compositing manager based on Clutter
|
||||
|
||||
License: GPLv2+
|
||||
@ -51,6 +51,10 @@ Patch9: 0001-main-be-more-aggressive-in-assuming-X11-backend.patch
|
||||
# Fixes --replace
|
||||
Patch10: 0001-backend-Clean-up-renderer-after-clutter-backendm.patch
|
||||
|
||||
# Fixes a race in wl_seat capabilities (rhbz#2003032)
|
||||
# https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/77
|
||||
Patch11: 0001-wayland-Avoid-a-race-in-wl_seat-capabilities.patch
|
||||
|
||||
BuildRequires: chrpath
|
||||
BuildRequires: pango-devel
|
||||
BuildRequires: startup-notification-devel
|
||||
@ -196,6 +200,10 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/%{name}.desktop
|
||||
%{_datadir}/mutter-%{mutter_api_version}/tests
|
||||
|
||||
%changelog
|
||||
* Fri Sep 10 2021 Olivier Fourdan <ofourdan@redhat.com> - 40.4-3
|
||||
- Fixes a race in wl_seat capabilities
|
||||
Resolves: #2003032
|
||||
|
||||
* Wed Aug 27 2021 Florian Müllner <fmuellner@redhat.com> - 40.4-2
|
||||
- Remove firstboot(windowmanager) provide
|
||||
Resolves: #1975355
|
||||
|
Loading…
Reference in New Issue
Block a user