From 4d4e8e586233344bf4d7d04d49b8cfb47bd98fc2 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Sat, 3 Dec 2022 09:25:52 -0300 Subject: [PATCH] screen-cast/src: Ceil cursor buffer size meta_screen_cast_stream_src_set_cursor_sprite_metadata() receives the cursor sprite, position, and scale, and with that it downloads the cursor sprite by drawing it into a separate framebuffer, then calls cogl_framebuffer_read_pixels() in it - this is the offscren path that is very common when using screen capturing applications such as OBS Studio. There's a sneaky issue in this code path though: the 'scale' value is a float. The cursor size is then determined by multiplying the sprite width and height - two integer variables - by scale, and this relies on standard float-to-int conversions. This is problematic as sometimes the rounded values disagree with what is expected by cogl_framebuffer_read_pixels(). If the packing of either the cursor width or height is off by one, glReadPixels() will try to write into off bounds, which crashes. This can be reproduced by enabling fractional scaling, setting a 150% zoom level, on a 4K screen, and opening any commit with an image diff in gitlab.gnome.org, all while screencasting. When hovering the new image, the cursor sprite will be such that it triggers this code path, and reproduces this issue. Fix this by always ceiling the cursor sprite sizes. Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/2542 Part-of: --- src/backends/meta-screen-cast-stream-src.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c index 7914d02d2..fbb5eaf66 100644 --- a/src/backends/meta-screen-cast-stream-src.c +++ b/src/backends/meta-screen-cast-stream-src.c @@ -445,8 +445,8 @@ meta_screen_cast_stream_src_set_cursor_sprite_metadata (MetaScreenCastStreamSrc texture_width = cogl_texture_get_width (cursor_texture); texture_height = cogl_texture_get_height (cursor_texture); - bitmap_width = texture_width * scale; - bitmap_height = texture_height * scale; + bitmap_width = ceilf (texture_width * scale); + bitmap_height = ceilf (texture_height * scale); spa_meta_bitmap->size.width = bitmap_width; spa_meta_bitmap->size.height = bitmap_height;