wayland/xdg-shell: Warn when invalid geometry is set

A client is not allowed to send an empty window geometry, and it is
specified that if it does so an error should be raised. Respect this
rule, ignore bogus geometries sent by clients with a warning.

Also add a soft assert that we don't try to "resend" a configuration
that was never sent, as doing so would result in SIGFPE as the geometry
scale is 0.

This fixes a SIGFPE crash occurring when a client did this.

Related: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/2808
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1527
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1557>
This commit is contained in:
Jonas Ådahl
2020-11-11 10:49:25 +01:00
committed by Marge Bot
parent 4d15438d66
commit d2c798838e
6 changed files with 317 additions and 0 deletions

View File

@ -1316,6 +1316,15 @@ zxdg_surface_v6_set_window_geometry (struct wl_client *client,
MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource);
MetaWaylandSurfaceState *pending;
if (width == 0 || height == 0)
{
g_warning ("Invalid geometry %dx%d+%d+%d set on xdg_surface@%d. Ignoring for "
"now, but this will result in client termination in the future.",
width, height, x, y,
wl_resource_get_id (resource));
return;
}
pending = meta_wayland_surface_get_pending_state (surface);
pending->has_new_geometry = TRUE;
pending->new_geometry.x = x;

View File

@ -1486,6 +1486,15 @@ xdg_surface_set_window_geometry (struct wl_client *client,
MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource);
MetaWaylandSurfaceState *pending;
if (width == 0 || height == 0)
{
g_warning ("Invalid geometry %dx%d+%d+%d set on xdg_surface@%d. Ignoring for "
"now, but this will result in client termination in the future.",
width, height, x, y,
wl_resource_get_id (resource));
return;
}
pending = meta_wayland_surface_get_pending_state (surface);
pending->has_new_geometry = TRUE;
pending->new_geometry.x = x;

View File

@ -53,6 +53,7 @@ struct _MetaWindowWayland
GList *pending_configurations;
gboolean has_pending_state_change;
gboolean has_last_sent_configuration;
int last_sent_x;
int last_sent_y;
int last_sent_width;
@ -188,6 +189,8 @@ surface_state_changed (MetaWindow *window)
if (window->unmanaging)
return;
g_return_if_fail (wl_window->has_last_sent_configuration);
configuration =
meta_wayland_window_configuration_new (wl_window->last_sent_x,
wl_window->last_sent_y,
@ -385,6 +388,7 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
}
}
wl_window->has_last_sent_configuration = TRUE;
wl_window->last_sent_x = configured_x;
wl_window->last_sent_y = configured_y;
wl_window->last_sent_width = configured_width;