parent
							
								
									e1c6c107de
								
							
						
					
					
						commit
						4c4e4b60f3
					
				| @ -18,7 +18,7 @@ | |||||||
| Summary: The GIMP ToolKit (GTK+), a library for creating GUIs for X | Summary: The GIMP ToolKit (GTK+), a library for creating GUIs for X | ||||||
| Name: gtk3 | Name: gtk3 | ||||||
| Version: 3.19.7 | Version: 3.19.7 | ||||||
| Release: 1%{?dist} | Release: 2%{?dist} | ||||||
| License: LGPLv2+ | License: LGPLv2+ | ||||||
| Group: System Environment/Libraries | Group: System Environment/Libraries | ||||||
| URL: http://www.gtk.org | URL: http://www.gtk.org | ||||||
| @ -96,6 +96,8 @@ Obsoletes: oxygen-gtk3 < 2:1.4.1 | |||||||
| # for file triggers | # for file triggers | ||||||
| Requires: glib2 >= 2.45.4-2 | Requires: glib2 >= 2.45.4-2 | ||||||
| 
 | 
 | ||||||
|  | Patch0: use-memfd.patch | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| %description | %description | ||||||
| GTK+ is a multi-platform toolkit for creating graphical user | GTK+ is a multi-platform toolkit for creating graphical user | ||||||
| @ -167,6 +169,7 @@ the functionality of the installed %{name} package. | |||||||
| 
 | 
 | ||||||
| %prep | %prep | ||||||
| %setup -q -n gtk+-%{version} | %setup -q -n gtk+-%{version} | ||||||
|  | %patch0 -p1 -b .use-memfd | ||||||
| 
 | 
 | ||||||
| %build | %build | ||||||
| 
 | 
 | ||||||
| @ -340,6 +343,10 @@ gtk-query-immodules-3.0-%{__isa_bits} --update-cache | |||||||
| %{_datadir}/installed-tests | %{_datadir}/installed-tests | ||||||
| 
 | 
 | ||||||
| %changelog | %changelog | ||||||
|  | * Mon Jan 25 2016 Ray Strode <rstrode@redhat.com> - 3.19.7-2 | ||||||
|  | - fix SIGBUG crasher in wayland | ||||||
|  |   Related: #1300390 | ||||||
|  | 
 | ||||||
| * Wed Jan 20 2016 Kalev Lember <klember@redhat.com> - 3.19.7-1 | * Wed Jan 20 2016 Kalev Lember <klember@redhat.com> - 3.19.7-1 | ||||||
| - Update to 3.19.7 | - Update to 3.19.7 | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										790
									
								
								use-memfd.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										790
									
								
								use-memfd.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,790 @@ | |||||||
|  | From 31e75c3e5c4f59b603602420d2708588091a07b2 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ray Strode <rstrode@redhat.com> | ||||||
|  | Date: Wed, 20 Jan 2016 12:22:29 -0500 | ||||||
|  | Subject: [PATCH 1/6] wayland: unlink shm file earlier in create function | ||||||
|  | 
 | ||||||
|  | create_shm_pool unlinks the temporary file a little, | ||||||
|  | too late. It should be unlinked before ftruncate() | ||||||
|  | is called for two reasons: | ||||||
|  | 
 | ||||||
|  | 1) if ftruncate fails, the file is currently not | ||||||
|  | getting cleaned up at all | ||||||
|  | 2) in theory, if the file is public some other process | ||||||
|  | could muck with it | ||||||
|  | 
 | ||||||
|  | This commit just moves the unlink call a little higher | ||||||
|  | up. | ||||||
|  | 
 | ||||||
|  | https://bugzilla.gnome.org/show_bug.cgi?id=760897 | ||||||
|  | ---
 | ||||||
|  |  gdk/wayland/gdkdisplay-wayland.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | index 97eebca..2f0c64e 100644
 | ||||||
|  | --- a/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | +++ b/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | @@ -914,73 +914,73 @@ buffer_release_callback (void             *_data,
 | ||||||
|  |    cairo_surface_t *surface = _data; | ||||||
|  |    GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key); | ||||||
|  |   | ||||||
|  |    data->busy = FALSE; | ||||||
|  |    cairo_surface_destroy (surface); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static const struct wl_buffer_listener buffer_listener = { | ||||||
|  |    buffer_release_callback | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static struct wl_shm_pool * | ||||||
|  |  create_shm_pool (struct wl_shm  *shm, | ||||||
|  |                   int             width, | ||||||
|  |                   int             height, | ||||||
|  |                   size_t         *buf_length, | ||||||
|  |                   void          **data_out) | ||||||
|  |  { | ||||||
|  |    char filename[] = "/tmp/wayland-shm-XXXXXX"; | ||||||
|  |    struct wl_shm_pool *pool; | ||||||
|  |    int fd, size, stride; | ||||||
|  |    void *data; | ||||||
|  |   | ||||||
|  |    fd = mkstemp (filename); | ||||||
|  |    if (fd < 0) | ||||||
|  |      { | ||||||
|  |        g_critical (G_STRLOC ": Unable to create temporary file (%s): %s", | ||||||
|  |                    filename, g_strerror (errno)); | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  | +  unlink (filename);
 | ||||||
|  |   | ||||||
|  |    stride = width * 4; | ||||||
|  |    size = stride * height; | ||||||
|  |    if (ftruncate (fd, size) < 0) | ||||||
|  |      { | ||||||
|  |        g_critical (G_STRLOC ": Truncating temporary file failed: %s", | ||||||
|  |                    g_strerror (errno)); | ||||||
|  |        close (fd); | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | ||||||
|  | -  unlink (filename);
 | ||||||
|  |   | ||||||
|  |    if (data == MAP_FAILED) | ||||||
|  |      { | ||||||
|  |        g_critical (G_STRLOC ": mmap'ping temporary file failed: %s", | ||||||
|  |                    g_strerror (errno)); | ||||||
|  |        close (fd); | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    pool = wl_shm_create_pool (shm, fd, size); | ||||||
|  |   | ||||||
|  |    close (fd); | ||||||
|  |   | ||||||
|  |    *data_out = data; | ||||||
|  |    *buf_length = size; | ||||||
|  |   | ||||||
|  |    return pool; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  |  gdk_wayland_cairo_surface_destroy (void *p) | ||||||
|  |  { | ||||||
|  |    GdkWaylandCairoSurfaceData *data = p; | ||||||
|  |   | ||||||
|  |    if (data->buffer) | ||||||
|  |      wl_buffer_destroy (data->buffer); | ||||||
|  |   | ||||||
|  |    if (data->pool) | ||||||
|  |      wl_shm_pool_destroy (data->pool); | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.7.0 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | From 743f5ef21afe0c00aa572d49d197658aa9613a01 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ray Strode <rstrode@redhat.com> | ||||||
|  | Date: Wed, 20 Jan 2016 11:40:34 -0500 | ||||||
|  | Subject: [PATCH 2/6] wayland: clean up stride calculation when creating shm | ||||||
|  |  surface | ||||||
|  | 
 | ||||||
|  | Right now, we assume the stride for the image surface needs to | ||||||
|  | be 4 byte aligned.  This is, in fact, true, but it's better to | ||||||
|  | ask cairo for the alignment requirement directly rather than | ||||||
|  | assume we know the alignment rules. | ||||||
|  | 
 | ||||||
|  | This commit changes the code to use cairo_format_stride_for_width | ||||||
|  | to calculate a suitable rowstride for pixman. | ||||||
|  | 
 | ||||||
|  | https://bugzilla.gnome.org/show_bug.cgi?id=760897 | ||||||
|  | ---
 | ||||||
|  |  gdk/wayland/gdkdisplay-wayland.c | 6 +++--- | ||||||
|  |  1 file changed, 3 insertions(+), 3 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | index 2f0c64e..bf3c20c 100644
 | ||||||
|  | --- a/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | +++ b/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | @@ -978,76 +978,76 @@ gdk_wayland_cairo_surface_destroy (void *p)
 | ||||||
|  |  { | ||||||
|  |    GdkWaylandCairoSurfaceData *data = p; | ||||||
|  |   | ||||||
|  |    if (data->buffer) | ||||||
|  |      wl_buffer_destroy (data->buffer); | ||||||
|  |   | ||||||
|  |    if (data->pool) | ||||||
|  |      wl_shm_pool_destroy (data->pool); | ||||||
|  |   | ||||||
|  |    munmap (data->buf, data->buf_length); | ||||||
|  |    g_free (data); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  cairo_surface_t * | ||||||
|  |  _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display, | ||||||
|  |                                           int                width, | ||||||
|  |                                           int                height, | ||||||
|  |                                           guint              scale) | ||||||
|  |  { | ||||||
|  |    GdkWaylandCairoSurfaceData *data; | ||||||
|  |    cairo_surface_t *surface = NULL; | ||||||
|  |    cairo_status_t status; | ||||||
|  |    int stride; | ||||||
|  |   | ||||||
|  |    data = g_new (GdkWaylandCairoSurfaceData, 1); | ||||||
|  |    data->display = display; | ||||||
|  |    data->buffer = NULL; | ||||||
|  |    data->scale = scale; | ||||||
|  |    data->busy = FALSE; | ||||||
|  |   | ||||||
|  | -  stride = width * 4;
 | ||||||
|  | +  stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width*scale);
 | ||||||
|  |   | ||||||
|  |    data->pool = create_shm_pool (display->shm, | ||||||
|  |                                  width*scale, height*scale, | ||||||
|  |                                  &data->buf_length, | ||||||
|  |                                  &data->buf); | ||||||
|  |   | ||||||
|  |    surface = cairo_image_surface_create_for_data (data->buf, | ||||||
|  |                                                   CAIRO_FORMAT_ARGB32, | ||||||
|  |                                                   width*scale, | ||||||
|  |                                                   height*scale, | ||||||
|  | -                                                 stride*scale);
 | ||||||
|  | +                                                 stride);
 | ||||||
|  |   | ||||||
|  |    data->buffer = wl_shm_pool_create_buffer (data->pool, 0, | ||||||
|  |                                              width*scale, height*scale, | ||||||
|  | -                                            stride*scale, WL_SHM_FORMAT_ARGB8888);
 | ||||||
|  | +                                            stride, WL_SHM_FORMAT_ARGB8888);
 | ||||||
|  |    wl_buffer_add_listener (data->buffer, &buffer_listener, surface); | ||||||
|  |   | ||||||
|  |    cairo_surface_set_user_data (surface, &gdk_wayland_cairo_key, | ||||||
|  |                                 data, gdk_wayland_cairo_surface_destroy); | ||||||
|  |   | ||||||
|  |    cairo_surface_set_device_scale (surface, scale, scale); | ||||||
|  |   | ||||||
|  |    status = cairo_surface_status (surface); | ||||||
|  |    if (status != CAIRO_STATUS_SUCCESS) | ||||||
|  |      { | ||||||
|  |        g_critical (G_STRLOC ": Unable to create Cairo image surface: %s", | ||||||
|  |                    cairo_status_to_string (status)); | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    return surface; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  struct wl_buffer * | ||||||
|  |  _gdk_wayland_shm_surface_get_wl_buffer (cairo_surface_t *surface) | ||||||
|  |  { | ||||||
|  |    GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key); | ||||||
|  |    return data->buffer; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  void | ||||||
|  |  _gdk_wayland_shm_surface_set_busy (cairo_surface_t *surface) | ||||||
|  |  { | ||||||
|  |    GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key); | ||||||
|  |    data->busy = TRUE; | ||||||
|  |    cairo_surface_reference (surface); | ||||||
|  | -- 
 | ||||||
|  | 2.7.0 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | From 2e704d3c0f7daaf38701d341186178c2adc442d1 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ray Strode <rstrode@redhat.com> | ||||||
|  | Date: Wed, 20 Jan 2016 12:35:44 -0500 | ||||||
|  | Subject: [PATCH 3/6] wayland: don't pass in width and height to | ||||||
|  |  create_shm_pool | ||||||
|  | 
 | ||||||
|  | create_shm_pool doesn't need the width or height, it just needs | ||||||
|  | the total size.  By passing it in, we're requiring it to redo | ||||||
|  | stride calculation unnecessarily. | ||||||
|  | 
 | ||||||
|  | This commit drops the width and height parameters and makes the | ||||||
|  | function just take the total size directly. | ||||||
|  | 
 | ||||||
|  | https://bugzilla.gnome.org/show_bug.cgi?id=760897 | ||||||
|  | ---
 | ||||||
|  |  gdk/wayland/gdkdisplay-wayland.c | 9 +++------ | ||||||
|  |  1 file changed, 3 insertions(+), 6 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | index bf3c20c..7c19a5c 100644
 | ||||||
|  | --- a/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | +++ b/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | @@ -897,81 +897,78 @@ gdk_wayland_display_get_xdg_shell (GdkDisplay *display)
 | ||||||
|  |   | ||||||
|  |  static const cairo_user_data_key_t gdk_wayland_cairo_key; | ||||||
|  |   | ||||||
|  |  typedef struct _GdkWaylandCairoSurfaceData { | ||||||
|  |    gpointer buf; | ||||||
|  |    size_t buf_length; | ||||||
|  |    struct wl_shm_pool *pool; | ||||||
|  |    struct wl_buffer *buffer; | ||||||
|  |    GdkWaylandDisplay *display; | ||||||
|  |    uint32_t scale; | ||||||
|  |    gboolean busy; | ||||||
|  |  } GdkWaylandCairoSurfaceData; | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  |  buffer_release_callback (void             *_data, | ||||||
|  |                           struct wl_buffer *wl_buffer) | ||||||
|  |  { | ||||||
|  |    cairo_surface_t *surface = _data; | ||||||
|  |    GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key); | ||||||
|  |   | ||||||
|  |    data->busy = FALSE; | ||||||
|  |    cairo_surface_destroy (surface); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static const struct wl_buffer_listener buffer_listener = { | ||||||
|  |    buffer_release_callback | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static struct wl_shm_pool * | ||||||
|  |  create_shm_pool (struct wl_shm  *shm, | ||||||
|  | -                 int             width,
 | ||||||
|  | -                 int             height,
 | ||||||
|  | +                 int             size,
 | ||||||
|  |                   size_t         *buf_length, | ||||||
|  |                   void          **data_out) | ||||||
|  |  { | ||||||
|  |    char filename[] = "/tmp/wayland-shm-XXXXXX"; | ||||||
|  |    struct wl_shm_pool *pool; | ||||||
|  | -  int fd, size, stride;
 | ||||||
|  | +  int fd;
 | ||||||
|  |    void *data; | ||||||
|  |   | ||||||
|  |    fd = mkstemp (filename); | ||||||
|  |    if (fd < 0) | ||||||
|  |      { | ||||||
|  |        g_critical (G_STRLOC ": Unable to create temporary file (%s): %s", | ||||||
|  |                    filename, g_strerror (errno)); | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  |    unlink (filename); | ||||||
|  |   | ||||||
|  | -  stride = width * 4;
 | ||||||
|  | -  size = stride * height;
 | ||||||
|  |    if (ftruncate (fd, size) < 0) | ||||||
|  |      { | ||||||
|  |        g_critical (G_STRLOC ": Truncating temporary file failed: %s", | ||||||
|  |                    g_strerror (errno)); | ||||||
|  |        close (fd); | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | ||||||
|  |   | ||||||
|  |    if (data == MAP_FAILED) | ||||||
|  |      { | ||||||
|  |        g_critical (G_STRLOC ": mmap'ping temporary file failed: %s", | ||||||
|  |                    g_strerror (errno)); | ||||||
|  |        close (fd); | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    pool = wl_shm_create_pool (shm, fd, size); | ||||||
|  |   | ||||||
|  |    close (fd); | ||||||
|  |   | ||||||
|  |    *data_out = data; | ||||||
|  |    *buf_length = size; | ||||||
|  |   | ||||||
|  |    return pool; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  |  gdk_wayland_cairo_surface_destroy (void *p) | ||||||
|  | @@ -981,61 +978,61 @@ gdk_wayland_cairo_surface_destroy (void *p)
 | ||||||
|  |    if (data->buffer) | ||||||
|  |      wl_buffer_destroy (data->buffer); | ||||||
|  |   | ||||||
|  |    if (data->pool) | ||||||
|  |      wl_shm_pool_destroy (data->pool); | ||||||
|  |   | ||||||
|  |    munmap (data->buf, data->buf_length); | ||||||
|  |    g_free (data); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  cairo_surface_t * | ||||||
|  |  _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display, | ||||||
|  |                                           int                width, | ||||||
|  |                                           int                height, | ||||||
|  |                                           guint              scale) | ||||||
|  |  { | ||||||
|  |    GdkWaylandCairoSurfaceData *data; | ||||||
|  |    cairo_surface_t *surface = NULL; | ||||||
|  |    cairo_status_t status; | ||||||
|  |    int stride; | ||||||
|  |   | ||||||
|  |    data = g_new (GdkWaylandCairoSurfaceData, 1); | ||||||
|  |    data->display = display; | ||||||
|  |    data->buffer = NULL; | ||||||
|  |    data->scale = scale; | ||||||
|  |    data->busy = FALSE; | ||||||
|  |   | ||||||
|  |    stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width*scale); | ||||||
|  |   | ||||||
|  |    data->pool = create_shm_pool (display->shm, | ||||||
|  | -                                width*scale, height*scale,
 | ||||||
|  | +                                height*scale*stride,
 | ||||||
|  |                                  &data->buf_length, | ||||||
|  |                                  &data->buf); | ||||||
|  |   | ||||||
|  |    surface = cairo_image_surface_create_for_data (data->buf, | ||||||
|  |                                                   CAIRO_FORMAT_ARGB32, | ||||||
|  |                                                   width*scale, | ||||||
|  |                                                   height*scale, | ||||||
|  |                                                   stride); | ||||||
|  |   | ||||||
|  |    data->buffer = wl_shm_pool_create_buffer (data->pool, 0, | ||||||
|  |                                              width*scale, height*scale, | ||||||
|  |                                              stride, WL_SHM_FORMAT_ARGB8888); | ||||||
|  |    wl_buffer_add_listener (data->buffer, &buffer_listener, surface); | ||||||
|  |   | ||||||
|  |    cairo_surface_set_user_data (surface, &gdk_wayland_cairo_key, | ||||||
|  |                                 data, gdk_wayland_cairo_surface_destroy); | ||||||
|  |   | ||||||
|  |    cairo_surface_set_device_scale (surface, scale, scale); | ||||||
|  |   | ||||||
|  |    status = cairo_surface_status (surface); | ||||||
|  |    if (status != CAIRO_STATUS_SUCCESS) | ||||||
|  |      { | ||||||
|  |        g_critical (G_STRLOC ": Unable to create Cairo image surface: %s", | ||||||
|  |                    cairo_status_to_string (status)); | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    return surface; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  struct wl_buffer * | ||||||
|  | -- 
 | ||||||
|  | 2.7.0 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | From 8717b4221f634e321aee80bc8accb60b6a24552d Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Matthias Clasen <mclasen@redhat.com> | ||||||
|  | Date: Thu, 21 Jan 2016 22:53:06 -0500 | ||||||
|  | Subject: [PATCH 4/6] wayland: Don't hardcode /tmp | ||||||
|  | 
 | ||||||
|  | As pointed out in https://bugzilla.gnome.org/show_bug.cgi?id=760964, | ||||||
|  | we should use the GLib facilities for determining the preferred | ||||||
|  | location for temporary files. | ||||||
|  | ---
 | ||||||
|  |  gdk/wayland/gdkdisplay-wayland.c | 15 ++++++++++----- | ||||||
|  |  1 file changed, 10 insertions(+), 5 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | index 7c19a5c..5e88d96 100644
 | ||||||
|  | --- a/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | +++ b/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | @@ -901,95 +901,100 @@ typedef struct _GdkWaylandCairoSurfaceData {
 | ||||||
|  |    gpointer buf; | ||||||
|  |    size_t buf_length; | ||||||
|  |    struct wl_shm_pool *pool; | ||||||
|  |    struct wl_buffer *buffer; | ||||||
|  |    GdkWaylandDisplay *display; | ||||||
|  |    uint32_t scale; | ||||||
|  |    gboolean busy; | ||||||
|  |  } GdkWaylandCairoSurfaceData; | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  |  buffer_release_callback (void             *_data, | ||||||
|  |                           struct wl_buffer *wl_buffer) | ||||||
|  |  { | ||||||
|  |    cairo_surface_t *surface = _data; | ||||||
|  |    GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key); | ||||||
|  |   | ||||||
|  |    data->busy = FALSE; | ||||||
|  |    cairo_surface_destroy (surface); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static const struct wl_buffer_listener buffer_listener = { | ||||||
|  |    buffer_release_callback | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static struct wl_shm_pool * | ||||||
|  |  create_shm_pool (struct wl_shm  *shm, | ||||||
|  |                   int             size, | ||||||
|  |                   size_t         *buf_length, | ||||||
|  |                   void          **data_out) | ||||||
|  |  { | ||||||
|  | -  char filename[] = "/tmp/wayland-shm-XXXXXX";
 | ||||||
|  | +  char *filename;
 | ||||||
|  |    struct wl_shm_pool *pool; | ||||||
|  |    int fd; | ||||||
|  |    void *data; | ||||||
|  |   | ||||||
|  | +  filename = g_strconcat (g_get_tmp_dir (), G_DIR_SEPARATOR_S, "wayland-shm-XXXXXX", NULL);
 | ||||||
|  |    fd = mkstemp (filename); | ||||||
|  |    if (fd < 0) | ||||||
|  |      { | ||||||
|  |        g_critical (G_STRLOC ": Unable to create temporary file (%s): %s", | ||||||
|  |                    filename, g_strerror (errno)); | ||||||
|  | +      g_free (filename);
 | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  |    unlink (filename); | ||||||
|  |   | ||||||
|  |    if (ftruncate (fd, size) < 0) | ||||||
|  |      { | ||||||
|  | -      g_critical (G_STRLOC ": Truncating temporary file failed: %s",
 | ||||||
|  | -                  g_strerror (errno));
 | ||||||
|  | +      g_critical (G_STRLOC ": Truncating temporary file (%s) failed: %s",
 | ||||||
|  | +                  filename, g_strerror (errno));
 | ||||||
|  | +      g_free (filename);
 | ||||||
|  |        close (fd); | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | ||||||
|  |   | ||||||
|  |    if (data == MAP_FAILED) | ||||||
|  |      { | ||||||
|  | -      g_critical (G_STRLOC ": mmap'ping temporary file failed: %s",
 | ||||||
|  | -                  g_strerror (errno));
 | ||||||
|  | +      g_critical (G_STRLOC ": mmap'ping temporary file (%s) failed: %s",
 | ||||||
|  | +                  filename, g_strerror (errno));
 | ||||||
|  | +      g_free (filename);
 | ||||||
|  |        close (fd); | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    pool = wl_shm_create_pool (shm, fd, size); | ||||||
|  |   | ||||||
|  |    close (fd); | ||||||
|  | +  g_free (filename);
 | ||||||
|  |   | ||||||
|  |    *data_out = data; | ||||||
|  |    *buf_length = size; | ||||||
|  |   | ||||||
|  |    return pool; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  |  gdk_wayland_cairo_surface_destroy (void *p) | ||||||
|  |  { | ||||||
|  |    GdkWaylandCairoSurfaceData *data = p; | ||||||
|  |   | ||||||
|  |    if (data->buffer) | ||||||
|  |      wl_buffer_destroy (data->buffer); | ||||||
|  |   | ||||||
|  |    if (data->pool) | ||||||
|  |      wl_shm_pool_destroy (data->pool); | ||||||
|  |   | ||||||
|  |    munmap (data->buf, data->buf_length); | ||||||
|  |    g_free (data); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  cairo_surface_t * | ||||||
|  |  _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display, | ||||||
|  |                                           int                width, | ||||||
|  |                                           int                height, | ||||||
|  |                                           guint              scale) | ||||||
|  |  { | ||||||
|  |    GdkWaylandCairoSurfaceData *data; | ||||||
|  |    cairo_surface_t *surface = NULL; | ||||||
|  | -- 
 | ||||||
|  | 2.7.0 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | From e9ba1539160378dbf484e5760c1e54ca0415f939 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ray Strode <rstrode@redhat.com> | ||||||
|  | Date: Mon, 25 Jan 2016 11:41:23 -0500 | ||||||
|  | Subject: [PATCH 5/6] wayland: use memfd_create instead of open in tmpdir | ||||||
|  | 
 | ||||||
|  | The tmpdir is used for a wide assortment of things, and | ||||||
|  | can easily fill up. If it fills then desktop will start | ||||||
|  | crashing with SIGBUS errors. | ||||||
|  | 
 | ||||||
|  | This commit changes the shm pool allocation code, to use | ||||||
|  | memfd_create, instead, so the shared memory files will | ||||||
|  | be anonymous and not associated with /tmp | ||||||
|  | 
 | ||||||
|  | https://bugzilla.gnome.org/show_bug.cgi?id=761095 | ||||||
|  | ---
 | ||||||
|  |  gdk/wayland/gdkdisplay-wayland.c | 28 ++++++++++++---------------- | ||||||
|  |  1 file changed, 12 insertions(+), 16 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | index 5e88d96..360c489 100644
 | ||||||
|  | --- a/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | +++ b/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | @@ -1,55 +1,57 @@
 | ||||||
|  |  /* | ||||||
|  |   * Copyright © 2010 Intel Corporation | ||||||
|  |   * | ||||||
|  |   * This library is free software; you can redistribute it and/or | ||||||
|  |   * modify it under the terms of the GNU Library General Public | ||||||
|  |   * License as published by the Free Software Foundation; either | ||||||
|  |   * version 2 of the License, or (at your option) any later version. | ||||||
|  |   * | ||||||
|  |   * This library is distributed in the hope that it will be useful, | ||||||
|  |   * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||||
|  |   * Library General Public License for more details. | ||||||
|  |   * | ||||||
|  |   * You should have received a copy of the GNU Library General Public | ||||||
|  |   * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |   */ | ||||||
|  |   | ||||||
|  |  #include "config.h" | ||||||
|  |   | ||||||
|  |  #include <stdlib.h> | ||||||
|  |  #include <string.h> | ||||||
|  |  #include <errno.h> | ||||||
|  |  #include <unistd.h> | ||||||
|  |  #include <fcntl.h> | ||||||
|  | +#include <linux/memfd.h>
 | ||||||
|  |  #include <sys/mman.h> | ||||||
|  | +#include <sys/syscall.h>
 | ||||||
|  |   | ||||||
|  |  #include <glib.h> | ||||||
|  |  #include "gdkwayland.h" | ||||||
|  |  #include "gdkdisplay.h" | ||||||
|  |  #include "gdkdisplay-wayland.h" | ||||||
|  |  #include "gdkscreen.h" | ||||||
|  |  #include "gdkinternals.h" | ||||||
|  |  #include "gdkdeviceprivate.h" | ||||||
|  |  #include "gdkdevicemanager.h" | ||||||
|  |  #include "gdkkeysprivate.h" | ||||||
|  |  #include "gdkprivate-wayland.h" | ||||||
|  |  #include "gdkglcontext-wayland.h" | ||||||
|  |  #include "pointer-gestures-unstable-v1-client-protocol.h" | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  |   * SECTION:wayland_interaction | ||||||
|  |   * @Short_description: Wayland backend-specific functions | ||||||
|  |   * @Title: Wayland Interaction | ||||||
|  |   * | ||||||
|  |   * The functions in this section are specific to the GDK Wayland backend. | ||||||
|  |   * To use them, you need to include the `<gdk/gdkwayland.h>` header and use | ||||||
|  |   * the Wayland-specific pkg-config files to build your application (either | ||||||
|  |   * `gdk-wayland-3.0` or `gtk+-wayland-3.0`). | ||||||
|  |   * | ||||||
|  |   * To make your code compile with other GDK backends, guard backend-specific | ||||||
|  |   * calls by an ifdef as follows. Since GDK may be built with multiple | ||||||
|  |   * backends, you should also check for the backend that is in use (e.g. by | ||||||
|  |   * using the GDK_IS_WAYLAND_DISPLAY() macro). | ||||||
|  |   * |[<!-- language="C" --> | ||||||
|  |   * #ifdef GDK_WINDOWING_WAYLAND | ||||||
|  | @@ -901,100 +903,94 @@ typedef struct _GdkWaylandCairoSurfaceData {
 | ||||||
|  |    gpointer buf; | ||||||
|  |    size_t buf_length; | ||||||
|  |    struct wl_shm_pool *pool; | ||||||
|  |    struct wl_buffer *buffer; | ||||||
|  |    GdkWaylandDisplay *display; | ||||||
|  |    uint32_t scale; | ||||||
|  |    gboolean busy; | ||||||
|  |  } GdkWaylandCairoSurfaceData; | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  |  buffer_release_callback (void             *_data, | ||||||
|  |                           struct wl_buffer *wl_buffer) | ||||||
|  |  { | ||||||
|  |    cairo_surface_t *surface = _data; | ||||||
|  |    GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key); | ||||||
|  |   | ||||||
|  |    data->busy = FALSE; | ||||||
|  |    cairo_surface_destroy (surface); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static const struct wl_buffer_listener buffer_listener = { | ||||||
|  |    buffer_release_callback | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static struct wl_shm_pool * | ||||||
|  |  create_shm_pool (struct wl_shm  *shm, | ||||||
|  |                   int             size, | ||||||
|  |                   size_t         *buf_length, | ||||||
|  |                   void          **data_out) | ||||||
|  |  { | ||||||
|  | -  char *filename;
 | ||||||
|  |    struct wl_shm_pool *pool; | ||||||
|  | -  int fd;
 | ||||||
|  | +  int ret, fd;
 | ||||||
|  |    void *data; | ||||||
|  |   | ||||||
|  | -  filename = g_strconcat (g_get_tmp_dir (), G_DIR_SEPARATOR_S, "wayland-shm-XXXXXX", NULL);
 | ||||||
|  | -  fd = mkstemp (filename);
 | ||||||
|  | -  if (fd < 0)
 | ||||||
|  | +  ret = syscall (SYS_memfd_create, "gdk-wayland", MFD_CLOEXEC);
 | ||||||
|  | +
 | ||||||
|  | +  if (ret < 0)
 | ||||||
|  |      { | ||||||
|  | -      g_critical (G_STRLOC ": Unable to create temporary file (%s): %s",
 | ||||||
|  | -                  filename, g_strerror (errno));
 | ||||||
|  | -      g_free (filename);
 | ||||||
|  | +      g_critical (G_STRLOC ": creating shared memory file failed: %s",
 | ||||||
|  | +                  g_strerror (-ret));
 | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  | -  unlink (filename);
 | ||||||
|  | +
 | ||||||
|  | +  fd = ret;
 | ||||||
|  |   | ||||||
|  |    if (ftruncate (fd, size) < 0) | ||||||
|  |      { | ||||||
|  | -      g_critical (G_STRLOC ": Truncating temporary file (%s) failed: %s",
 | ||||||
|  | -                  filename, g_strerror (errno));
 | ||||||
|  | -      g_free (filename);
 | ||||||
|  | +      g_critical (G_STRLOC ": Truncating shared memory file failed: %m");
 | ||||||
|  |        close (fd); | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | ||||||
|  |   | ||||||
|  |    if (data == MAP_FAILED) | ||||||
|  |      { | ||||||
|  | -      g_critical (G_STRLOC ": mmap'ping temporary file (%s) failed: %s",
 | ||||||
|  | -                  filename, g_strerror (errno));
 | ||||||
|  | -      g_free (filename);
 | ||||||
|  | +      g_critical (G_STRLOC ": mmap'ping shared memory file failed: %m");
 | ||||||
|  |        close (fd); | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    pool = wl_shm_create_pool (shm, fd, size); | ||||||
|  |   | ||||||
|  |    close (fd); | ||||||
|  | -  g_free (filename);
 | ||||||
|  |   | ||||||
|  |    *data_out = data; | ||||||
|  |    *buf_length = size; | ||||||
|  |   | ||||||
|  |    return pool; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  |  gdk_wayland_cairo_surface_destroy (void *p) | ||||||
|  |  { | ||||||
|  |    GdkWaylandCairoSurfaceData *data = p; | ||||||
|  |   | ||||||
|  |    if (data->buffer) | ||||||
|  |      wl_buffer_destroy (data->buffer); | ||||||
|  |   | ||||||
|  |    if (data->pool) | ||||||
|  |      wl_shm_pool_destroy (data->pool); | ||||||
|  |   | ||||||
|  |    munmap (data->buf, data->buf_length); | ||||||
|  |    g_free (data); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  cairo_surface_t * | ||||||
|  |  _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display, | ||||||
|  |                                           int                width, | ||||||
|  |                                           int                height, | ||||||
|  |                                           guint              scale) | ||||||
|  |  { | ||||||
|  |    GdkWaylandCairoSurfaceData *data; | ||||||
|  |    cairo_surface_t *surface = NULL; | ||||||
|  | -- 
 | ||||||
|  | 2.7.0 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | From ba8ce203ed2f1723b7f332fba1efb28f96f0a1c4 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ray Strode <rstrode@redhat.com> | ||||||
|  | Date: Mon, 25 Jan 2016 13:55:25 -0500 | ||||||
|  | Subject: [PATCH 6/6] wayland: __NR_memfd_create instead of SYS_memfd_create | ||||||
|  | 
 | ||||||
|  | It looks like the gnome-continuous headers haven't quite | ||||||
|  | caught up yet, so try __NR_memfd_create instead. | ||||||
|  | 
 | ||||||
|  | If that doesn't work, i'll likely just add in a fallback | ||||||
|  | code path. | ||||||
|  | ---
 | ||||||
|  |  gdk/wayland/gdkdisplay-wayland.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | index 360c489..f200800 100644
 | ||||||
|  | --- a/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | +++ b/gdk/wayland/gdkdisplay-wayland.c
 | ||||||
|  | @@ -907,61 +907,61 @@ typedef struct _GdkWaylandCairoSurfaceData {
 | ||||||
|  |    GdkWaylandDisplay *display; | ||||||
|  |    uint32_t scale; | ||||||
|  |    gboolean busy; | ||||||
|  |  } GdkWaylandCairoSurfaceData; | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  |  buffer_release_callback (void             *_data, | ||||||
|  |                           struct wl_buffer *wl_buffer) | ||||||
|  |  { | ||||||
|  |    cairo_surface_t *surface = _data; | ||||||
|  |    GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key); | ||||||
|  |   | ||||||
|  |    data->busy = FALSE; | ||||||
|  |    cairo_surface_destroy (surface); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static const struct wl_buffer_listener buffer_listener = { | ||||||
|  |    buffer_release_callback | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static struct wl_shm_pool * | ||||||
|  |  create_shm_pool (struct wl_shm  *shm, | ||||||
|  |                   int             size, | ||||||
|  |                   size_t         *buf_length, | ||||||
|  |                   void          **data_out) | ||||||
|  |  { | ||||||
|  |    struct wl_shm_pool *pool; | ||||||
|  |    int ret, fd; | ||||||
|  |    void *data; | ||||||
|  |   | ||||||
|  | -  ret = syscall (SYS_memfd_create, "gdk-wayland", MFD_CLOEXEC);
 | ||||||
|  | +  ret = syscall (__NR_memfd_create, "gdk-wayland", MFD_CLOEXEC);
 | ||||||
|  |   | ||||||
|  |    if (ret < 0) | ||||||
|  |      { | ||||||
|  |        g_critical (G_STRLOC ": creating shared memory file failed: %s", | ||||||
|  |                    g_strerror (-ret)); | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    fd = ret; | ||||||
|  |   | ||||||
|  |    if (ftruncate (fd, size) < 0) | ||||||
|  |      { | ||||||
|  |        g_critical (G_STRLOC ": Truncating shared memory file failed: %m"); | ||||||
|  |        close (fd); | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | ||||||
|  |   | ||||||
|  |    if (data == MAP_FAILED) | ||||||
|  |      { | ||||||
|  |        g_critical (G_STRLOC ": mmap'ping shared memory file failed: %m"); | ||||||
|  |        close (fd); | ||||||
|  |        return NULL; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |    pool = wl_shm_create_pool (shm, fd, size); | ||||||
|  |   | ||||||
|  |    close (fd); | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.7.0 | ||||||
|  | 
 | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user