import xorg-x11-server-Xwayland-21.1.3-2.el8

c8-beta imports/c8-beta/xorg-x11-server-Xwayland-21.1.3-2.el8
CentOS Sources 2022-03-29 09:22:12 -04:00 committed by Stepan Oksanichenko
parent 060e8cb862
commit fd636d789f
40 changed files with 428 additions and 3405 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/xwayland-21.1.1.tar.xz
SOURCES/xwayland-21.1.3.tar.xz

View File

@ -1 +1 @@
4eb5e22033c0c80c35480c9466e8041e914cac3a SOURCES/xwayland-21.1.1.tar.xz
ae980a7deeb7cad9f3cd253f3b1ddca5bb26aafa SOURCES/xwayland-21.1.3.tar.xz

View File

@ -0,0 +1,35 @@
From a8644465d98beb08759546711b77bb617861c67f Mon Sep 17 00:00:00 2001
From: Povilas Kanapickas <povilas@radix.lt>
Date: Tue, 14 Dec 2021 15:00:00 +0200
Subject: [PATCH xserver 1/4] record: Fix out of bounds access in
SwapCreateRegister()
ZDI-CAN-14952, CVE-2021-4011
This vulnerability was discovered and the fix was suggested by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit e56f61c79fc3cee26d83cda0f84ae56d5979f768)
---
record/record.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/record/record.c b/record/record.c
index be154525d..e123867a7 100644
--- a/record/record.c
+++ b/record/record.c
@@ -2516,8 +2516,8 @@ SwapCreateRegister(ClientPtr client, xRecordRegisterClientsReq * stuff)
swapl(pClientID);
}
if (stuff->nRanges >
- client->req_len - bytes_to_int32(sz_xRecordRegisterClientsReq)
- - stuff->nClients)
+ (client->req_len - bytes_to_int32(sz_xRecordRegisterClientsReq)
+ - stuff->nClients) / bytes_to_int32(sz_xRecordRange))
return BadLength;
RecordSwapRanges((xRecordRange *) pClientID, stuff->nRanges);
return Success;
--
2.33.1

View File

@ -1,257 +0,0 @@
From c7853c6de126f6794946c592deed205c0ddad2d9 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 3 Mar 2021 09:55:12 +0100
Subject: [PATCH xserver 01/27] xwayland: Move dmabuf interface to common
glamor code
This is preliminary work for hardware accelerated rendering with the
NVIDIA driver.
The EGLStream backend can possibly also use the dmabuf interface, so
move the relevant code from the GBM specific source to the common bits.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit ae225417c0a0828ffb24e11eb4b968c34692e25a)
---
hw/xwayland/xwayland-glamor-gbm.c | 73 ++---------------------------
hw/xwayland/xwayland-glamor.c | 76 +++++++++++++++++++++++++++++--
hw/xwayland/xwayland-screen.h | 1 +
3 files changed, 76 insertions(+), 74 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 221bf268a..73c69727e 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -56,7 +56,6 @@ struct xwl_gbm_private {
char *device_name;
struct gbm_device *gbm;
struct wl_drm *drm;
- struct zwp_linux_dmabuf_v1 *dmabuf;
int drm_fd;
int fd_render_node;
Bool drm_authenticated;
@@ -334,10 +333,10 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
}
}
- if (xwl_gbm->dmabuf && modifier_supported) {
+ if (xwl_screen->dmabuf && modifier_supported) {
struct zwp_linux_buffer_params_v1 *params;
- params = zwp_linux_dmabuf_v1_create_params(xwl_gbm->dmabuf);
+ params = zwp_linux_dmabuf_v1_create_params(xwl_screen->dmabuf);
for (i = 0; i < num_planes; i++) {
zwp_linux_buffer_params_v1_add(params, prime_fd, i,
offsets[i], strides[i],
@@ -604,7 +603,7 @@ glamor_get_formats(ScreenPtr screen,
/* Explicitly zero the count as the caller may ignore the return value */
*num_formats = 0;
- if (!xwl_gbm->dmabuf_capable || !xwl_gbm->dmabuf)
+ if (!xwl_gbm->dmabuf_capable || !xwl_screen->dmabuf)
return FALSE;
if (xwl_screen->num_formats == 0)
@@ -633,7 +632,7 @@ glamor_get_modifiers(ScreenPtr screen, uint32_t format,
/* Explicitly zero the count as the caller may ignore the return value */
*num_modifiers = 0;
- if (!xwl_gbm->dmabuf_capable || !xwl_gbm->dmabuf)
+ if (!xwl_gbm->dmabuf_capable || !xwl_screen->dmabuf)
return FALSE;
if (xwl_screen->num_formats == 0)
@@ -797,54 +796,6 @@ static const struct wl_drm_listener xwl_drm_listener = {
xwl_drm_handle_capabilities
};
-static void
-xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
- uint32_t format)
-{
-}
-
-static void
-xwl_dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
- uint32_t format, uint32_t modifier_hi,
- uint32_t modifier_lo)
-{
- struct xwl_screen *xwl_screen = data;
- struct xwl_format *xwl_format = NULL;
- int i;
-
- for (i = 0; i < xwl_screen->num_formats; i++) {
- if (xwl_screen->formats[i].format == format) {
- xwl_format = &xwl_screen->formats[i];
- break;
- }
- }
-
- if (xwl_format == NULL) {
- xwl_screen->num_formats++;
- xwl_screen->formats = realloc(xwl_screen->formats,
- xwl_screen->num_formats * sizeof(*xwl_format));
- if (!xwl_screen->formats)
- return;
- xwl_format = &xwl_screen->formats[xwl_screen->num_formats - 1];
- xwl_format->format = format;
- xwl_format->num_modifiers = 0;
- xwl_format->modifiers = NULL;
- }
-
- xwl_format->num_modifiers++;
- xwl_format->modifiers = realloc(xwl_format->modifiers,
- xwl_format->num_modifiers * sizeof(uint64_t));
- if (!xwl_format->modifiers)
- return;
- xwl_format->modifiers[xwl_format->num_modifiers - 1] = (uint64_t) modifier_lo;
- xwl_format->modifiers[xwl_format->num_modifiers - 1] |= (uint64_t) modifier_hi << 32;
-}
-
-static const struct zwp_linux_dmabuf_v1_listener xwl_dmabuf_listener = {
- .format = xwl_dmabuf_handle_format,
- .modifier = xwl_dmabuf_handle_modifier
-};
-
Bool
xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
uint32_t id, uint32_t version)
@@ -862,22 +813,6 @@ xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
return TRUE;
}
-Bool
-xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
- uint32_t id, uint32_t version)
-{
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-
- if (version < 3)
- return FALSE;
-
- xwl_gbm->dmabuf =
- wl_registry_bind(xwl_screen->registry, id, &zwp_linux_dmabuf_v1_interface, 3);
- zwp_linux_dmabuf_v1_add_listener(xwl_gbm->dmabuf, &xwl_dmabuf_listener, xwl_screen);
-
- return TRUE;
-}
-
static Bool
xwl_glamor_gbm_init_wl_registry(struct xwl_screen *xwl_screen,
struct wl_registry *wl_registry,
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index bcd07a1a5..cce0c911e 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -35,6 +35,10 @@
#include "glx_extinit.h"
#endif
+#include "linux-dmabuf-unstable-v1-client-protocol.h"
+#include "drm-client-protocol.h"
+#include <drm_fourcc.h>
+
#include "xwayland-glamor.h"
#include "xwayland-glx.h"
#include "xwayland-screen.h"
@@ -75,6 +79,68 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
xwl_screen->glamor_ctx = glamor_ctx;
}
+static void
+xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
+ uint32_t format)
+{
+}
+
+static void
+xwl_dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
+ uint32_t format, uint32_t modifier_hi,
+ uint32_t modifier_lo)
+{
+ struct xwl_screen *xwl_screen = data;
+ struct xwl_format *xwl_format = NULL;
+ int i;
+
+ for (i = 0; i < xwl_screen->num_formats; i++) {
+ if (xwl_screen->formats[i].format == format) {
+ xwl_format = &xwl_screen->formats[i];
+ break;
+ }
+ }
+
+ if (xwl_format == NULL) {
+ xwl_screen->num_formats++;
+ xwl_screen->formats = realloc(xwl_screen->formats,
+ xwl_screen->num_formats * sizeof(*xwl_format));
+ if (!xwl_screen->formats)
+ return;
+ xwl_format = &xwl_screen->formats[xwl_screen->num_formats - 1];
+ xwl_format->format = format;
+ xwl_format->num_modifiers = 0;
+ xwl_format->modifiers = NULL;
+ }
+
+ xwl_format->num_modifiers++;
+ xwl_format->modifiers = realloc(xwl_format->modifiers,
+ xwl_format->num_modifiers * sizeof(uint64_t));
+ if (!xwl_format->modifiers)
+ return;
+ xwl_format->modifiers[xwl_format->num_modifiers - 1] = (uint64_t) modifier_lo;
+ xwl_format->modifiers[xwl_format->num_modifiers - 1] |= (uint64_t) modifier_hi << 32;
+}
+
+static const struct zwp_linux_dmabuf_v1_listener xwl_dmabuf_listener = {
+ .format = xwl_dmabuf_handle_format,
+ .modifier = xwl_dmabuf_handle_modifier
+};
+
+Bool
+xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
+ uint32_t id, uint32_t version)
+{
+ if (version < 3)
+ return FALSE;
+
+ xwl_screen->dmabuf =
+ wl_registry_bind(xwl_screen->registry, id, &zwp_linux_dmabuf_v1_interface, 3);
+ zwp_linux_dmabuf_v1_add_listener(xwl_screen->dmabuf, &xwl_dmabuf_listener, xwl_screen);
+
+ return TRUE;
+}
+
void
xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
struct wl_registry *registry,
@@ -89,11 +155,11 @@ xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
version)) {
/* no-op */
} else if (xwl_screen->eglstream_backend.is_available &&
- xwl_screen->eglstream_backend.init_wl_registry(xwl_screen,
- registry,
- id,
- interface,
- version)) {
+ xwl_screen->eglstream_backend.init_wl_registry(xwl_screen,
+ registry,
+ id,
+ interface,
+ version)) {
/* no-op */
}
}
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
index 8d0b12705..5fe4712bd 100644
--- a/hw/xwayland/xwayland-screen.h
+++ b/hw/xwayland/xwayland-screen.h
@@ -83,6 +83,7 @@ struct xwl_screen {
struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
struct zwp_pointer_constraints_v1 *pointer_constraints;
struct zwp_xwayland_keyboard_grab_manager_v1 *wp_grab;
+ struct zwp_linux_dmabuf_v1 *dmabuf;
struct zxdg_output_manager_v1 *xdg_output_manager;
struct wp_viewporter *viewporter;
uint32_t serial;
--
2.31.1

View File

@ -0,0 +1,43 @@
From 0a7ed9ff7ea20f7b958a2ad9f9bd045080a3ad9a Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Mon, 15 Nov 2021 16:02:34 +0100
Subject: [PATCH xserver 1/4] xwayland/eglstream: Demote EGLstream device
warning
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If no EGLstream capable device is found at startup, Xwayland's EGLstream
backend will log an error message "glamor: No eglstream capable devices
found".
However, considering that the vast majority of drivers do not implement
EGLstream, the lack of EGLstream capable device is more of the norm than
the exception.
Change the error message to a log verbose message.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Simon Ser <contact@emersion.fr>
Reviewed-by: Jonas Ådahl <jadahl@gmail.com>
(cherry picked from commit 96c82befa2c3f3dc3534743c67cc003c2106e9b0)
---
hw/xwayland/xwayland-glamor-eglstream.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 8d18caaf5..93d192d58 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -1144,7 +1144,7 @@ xwl_eglstream_get_device(struct xwl_screen *xwl_screen)
free(devices);
out:
if (!device)
- ErrorF("glamor: No eglstream capable devices found\n");
+ LogMessageVerb(X_INFO, 3, "glamor: No eglstream capable devices found\n");
return device;
}
--
2.33.1

View File

@ -1,36 +0,0 @@
From 8c74023712a9e0d79ec669738b726e7dc821de68 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 23 Jun 2021 11:35:17 +0200
Subject: [PATCH xserver 1/2] xwayland/eglstream: Keep pending stream if the
pixmap didn't change
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If the pixmap does not actually change in set_window_pixmap(), there is
no need to invalidate the pending stream, if there's one.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Suggested-by: Michel Dänzer <mdaenzer@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit 2be9f795bc15012dc912f595003e01bb6aa66f54)
---
hw/xwayland/xwayland-glamor-eglstream.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 0affc954c..2eae9494c 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -377,7 +377,7 @@ xwl_eglstream_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
* attached, so the stream would be useless.
*/
old_pixmap = (*screen->GetWindowPixmap) (window);
- if (old_pixmap)
+ if (old_pixmap && old_pixmap != pixmap)
xwl_eglstream_maybe_set_pending_stream_invalid(old_pixmap);
xwl_screen->screen->SetWindowPixmap = xwl_eglstream->SetWindowPixmap;
--
2.31.1

View File

@ -0,0 +1,44 @@
From 3eb5445f6f7fa9f86de87adc768105d42bdbcf74 Mon Sep 17 00:00:00 2001
From: Povilas Kanapickas <povilas@radix.lt>
Date: Tue, 14 Dec 2021 15:00:01 +0200
Subject: [PATCH xserver 2/4] xfixes: Fix out of bounds access in
*ProcXFixesCreatePointerBarrier()
ZDI-CAN-14950, CVE-2021-4009
This vulnerability was discovered and the fix was suggested by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit b5196750099ae6ae582e1f46bd0a6dad29550e02)
---
xfixes/cursor.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/xfixes/cursor.c b/xfixes/cursor.c
index 60580b88f..c5d4554b2 100644
--- a/xfixes/cursor.c
+++ b/xfixes/cursor.c
@@ -1010,7 +1010,8 @@ ProcXFixesCreatePointerBarrier(ClientPtr client)
{
REQUEST(xXFixesCreatePointerBarrierReq);
- REQUEST_FIXED_SIZE(xXFixesCreatePointerBarrierReq, pad_to_int32(stuff->num_devices));
+ REQUEST_FIXED_SIZE(xXFixesCreatePointerBarrierReq,
+ pad_to_int32(stuff->num_devices * sizeof(CARD16)));
LEGAL_NEW_RESOURCE(stuff->barrier, client);
return XICreatePointerBarrier(client, stuff);
@@ -1027,7 +1028,8 @@ SProcXFixesCreatePointerBarrier(ClientPtr client)
swaps(&stuff->length);
swaps(&stuff->num_devices);
- REQUEST_FIXED_SIZE(xXFixesCreatePointerBarrierReq, pad_to_int32(stuff->num_devices));
+ REQUEST_FIXED_SIZE(xXFixesCreatePointerBarrierReq,
+ pad_to_int32(stuff->num_devices * sizeof(CARD16)));
swapl(&stuff->barrier);
swapl(&stuff->window);
--
2.33.1

View File

@ -1,292 +0,0 @@
From d9005a02e9c109e57dcc81b51de3b5778915af26 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Fri, 30 Apr 2021 09:56:05 +0200
Subject: [PATCH xserver 2/2] xwayland/eglstream: Remove stream validity
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
To avoid an EGL stream in the wrong state, if the window pixmap changed
before the stream was connected, we would still keep the pending stream
but mark it as invalid. Once the callback is received, the pending would
be simply discarded.
But all of this is actually to avoid a bug in egl-wayland, there should
not be any problem with Xwayland destroying an EGL stream while the
compositor is still using it.
With that bug now fixed in egl-wayland 1.1.7, we can safely drop all
that logic from Xwayland EGLstream backend.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1189
(cherry picked from commit 7d509b6f342d9732b567dc4efa867ea24919853b)
---
hw/xwayland/xwayland-glamor-eglstream.c | 165 ++++--------------------
1 file changed, 28 insertions(+), 137 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 2eae9494c..8d18caaf5 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -52,15 +52,6 @@
#include "wayland-eglstream-controller-client-protocol.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"
-struct xwl_eglstream_pending_stream {
- PixmapPtr pixmap;
- WindowPtr window;
-
- struct wl_callback *cb;
-
- Bool is_valid;
-};
-
struct xwl_eglstream_private {
EGLDeviceEXT egl_device;
struct wl_eglstream_display *display;
@@ -90,7 +81,7 @@ struct xwl_pixmap {
/* add any new <= 4-byte member here to avoid holes on 64-bit */
struct xwl_screen *xwl_screen;
struct wl_buffer *buffer;
- struct xwl_eglstream_pending_stream *pending_stream;
+ struct wl_callback *pending_cb;
Bool wait_for_buffer_release;
/* XWL_PIXMAP_EGLSTREAM. */
@@ -301,20 +292,12 @@ xwl_eglstream_destroy_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
free(xwl_pixmap);
}
-static void
-xwl_glamor_eglstream_destroy_pending_stream(struct xwl_eglstream_pending_stream *pending)
-{
- if (pending->cb)
- wl_callback_destroy(pending->cb);
- free(pending);
-}
-
static void
xwl_glamor_eglstream_remove_pending_stream(struct xwl_pixmap *xwl_pixmap)
{
- if (xwl_pixmap->pending_stream) {
- xwl_glamor_eglstream_destroy_pending_stream(xwl_pixmap->pending_stream);
- xwl_pixmap->pending_stream = NULL;
+ if (xwl_pixmap->pending_cb) {
+ wl_callback_destroy(xwl_pixmap->pending_cb);
+ xwl_pixmap->pending_cb = NULL;
}
}
@@ -338,27 +321,13 @@ xwl_glamor_eglstream_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
}
static void
-xwl_eglstream_maybe_set_pending_stream_invalid(PixmapPtr pixmap)
+xwl_eglstream_cancel_pending_stream(PixmapPtr pixmap)
{
struct xwl_pixmap *xwl_pixmap;
- struct xwl_eglstream_pending_stream *pending;
xwl_pixmap = xwl_pixmap_get(pixmap);
- if (!xwl_pixmap)
- return;
-
- pending = xwl_pixmap->pending_stream;
- if (!pending)
- return;
-
- pending->is_valid = FALSE;
-
- /* The compositor may still be using the stream, so we can't destroy
- * it yet. We'll only have a guarantee that the stream is safe to
- * destroy once we receive the pending wl_display_sync() for this
- * stream
- */
- pending->pixmap->refcnt++;
+ if (xwl_pixmap)
+ xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
}
static void
@@ -378,7 +347,7 @@ xwl_eglstream_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
*/
old_pixmap = (*screen->GetWindowPixmap) (window);
if (old_pixmap && old_pixmap != pixmap)
- xwl_eglstream_maybe_set_pending_stream_invalid(old_pixmap);
+ xwl_eglstream_cancel_pending_stream(old_pixmap);
xwl_screen->screen->SetWindowPixmap = xwl_eglstream->SetWindowPixmap;
(*xwl_screen->screen->SetWindowPixmap)(window, pixmap);
@@ -464,68 +433,19 @@ xwl_eglstream_print_error(EGLDisplay egl_display,
}
}
-/* Because we run asynchronously with our wayland compositor, it's possible
- * that an X client event could cause us to begin creating a stream for a
- * pixmap/window combo before the stream for the pixmap this window
- * previously used has been fully initialized. An example:
- *
- * - Start processing X client events.
- * - X window receives resize event, causing us to create a new pixmap and
- * begin creating the corresponding eglstream. This pixmap is known as
- * pixmap A.
- * - X window receives another resize event, and again changes its current
- * pixmap causing us to create another corresponding eglstream for the same
- * window. This pixmap is known as pixmap B.
- * - Start handling events from the wayland compositor.
- *
- * Since both pixmap A and B will have scheduled wl_display_sync events to
- * indicate when their respective streams are connected, we will receive each
- * callback in the original order the pixmaps were created. This means the
- * following would happen:
- *
- * - Receive pixmap A's stream callback, attach its stream to the surface of
- * the window that just orphaned it.
- * - Receive pixmap B's stream callback, fall over and fail because the
- * window's surface now incorrectly has pixmap A's stream attached to it.
- *
- * We work around this problem by keeping a pending stream associated with
- * the xwl_pixmap, which itself is associated with the window pixmap.
- * In the scenario listed above, this should happen:
- *
- * - Begin processing X events...
- * - A window is resized, a new window pixmap is created causing us to
- * add an eglstream (known as eglstream A) waiting for its consumer
- * to finish attachment.
- * - Resize on same window happens. We invalidate the previously pending
- * stream on the old window pixmap.
- * A new window pixmap is attached to the window and another pending
- * stream is created for that new pixmap (known as eglstream B).
- * - Begin processing Wayland events...
- * - Receive invalidated callback from compositor for eglstream A, destroy
- * stream.
- * - Receive callback from compositor for eglstream B, create producer.
- * - Success!
- */
static void
xwl_eglstream_consumer_ready_callback(void *data,
struct wl_callback *callback,
uint32_t time)
{
- struct xwl_eglstream_pending_stream *pending = data;
- PixmapPtr pixmap = pending->pixmap;
+ PixmapPtr pixmap = data;
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
struct xwl_screen *xwl_screen = xwl_pixmap->xwl_screen;
struct xwl_eglstream_private *xwl_eglstream =
xwl_eglstream_get(xwl_screen);
wl_callback_destroy(callback);
- pending->cb = NULL;
-
- if (!pending->is_valid) {
- xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
- dixDestroyPixmap(pixmap, 0);
- return;
- }
+ xwl_pixmap->pending_cb = NULL;
xwl_glamor_egl_make_current(xwl_screen);
@@ -541,42 +461,16 @@ xwl_eglstream_consumer_ready_callback(void *data,
ErrorF("eglstream: Failed to create EGLSurface for pixmap\n");
xwl_eglstream_print_error(xwl_screen->egl_display,
xwl_pixmap->stream, eglGetError());
- goto out;
+ } else {
+ DebugF("eglstream: completes eglstream for pixmap %p, congrats!\n",
+ pixmap);
}
-
- DebugF("eglstream: win %d completes eglstream for pixmap %p, congrats!\n",
- pending->window->drawable.id, pending->pixmap);
-
-out:
- xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
}
static const struct wl_callback_listener consumer_ready_listener = {
xwl_eglstream_consumer_ready_callback
};
-static struct xwl_eglstream_pending_stream *
-xwl_eglstream_queue_pending_stream(WindowPtr window, PixmapPtr pixmap)
-{
- struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
- struct xwl_screen *xwl_screen = xwl_pixmap->xwl_screen;
- struct xwl_eglstream_pending_stream *pending_stream;
-
- DebugF("eglstream: win %d queues new pending stream for pixmap %p\n",
- window->drawable.id, pixmap);
-
- pending_stream = calloc(1, sizeof(*pending_stream));
- pending_stream->window = window;
- pending_stream->pixmap = pixmap;
- pending_stream->is_valid = TRUE;
-
- pending_stream->cb = wl_display_sync(xwl_screen->display);
- wl_callback_add_listener(pending_stream->cb, &consumer_ready_listener,
- pending_stream);
-
- return pending_stream;
-}
-
static void
xwl_eglstream_buffer_release_callback(void *data)
{
@@ -656,9 +550,9 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
wl_eglstream_controller_attach_eglstream_consumer(
xwl_eglstream->controller, xwl_window->surface, xwl_pixmap->buffer);
- xwl_pixmap->pending_stream =
- xwl_eglstream_queue_pending_stream(window, pixmap);
-
+ xwl_pixmap->pending_cb = wl_display_sync(xwl_screen->display);
+ wl_callback_add_listener(xwl_pixmap->pending_cb, &consumer_ready_listener,
+ pixmap);
fail:
if (stream_fd >= 0)
close(stream_fd);
@@ -673,25 +567,22 @@ xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
if (xwl_pixmap) {
- struct xwl_eglstream_pending_stream *pending = xwl_pixmap->pending_stream;
-
- if (pending) {
+ if (xwl_pixmap->pending_cb) {
/* Wait for the compositor to finish connecting the consumer for
* this eglstream */
- assert(pending->is_valid);
-
return FALSE;
- } else {
- if (xwl_pixmap->surface != EGL_NO_SURFACE ||
- xwl_pixmap->type == XWL_PIXMAP_DMA_BUF)
- return TRUE;
-
- /* The pending stream got removed, we have a xwl_pixmap and
- * yet we do not have a surface.
- * So something went wrong with the surface creation, retry.
- */
- xwl_eglstream_destroy_pixmap_stream(xwl_pixmap);
}
+
+ if (xwl_pixmap->surface != EGL_NO_SURFACE ||
+ xwl_pixmap->type == XWL_PIXMAP_DMA_BUF) {
+ return TRUE;
+ }
+
+ /* The pending stream got removed, we have a xwl_pixmap and
+ * yet we do not have a surface.
+ * So something went wrong with the surface creation, retry.
+ */
+ xwl_eglstream_destroy_pixmap_stream(xwl_pixmap);
}
/* Glamor pixmap has no backing stream yet; begin making one and disallow
--
2.31.1

View File

@ -0,0 +1,88 @@
From a515f4f4336efb8a2adf9a3ac141129708297d80 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Mon, 29 Nov 2021 11:45:35 +0100
Subject: [PATCH xserver 2/4] xwayland/glamor: Change errors to verbose
messages
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On a normal startup sequence, the Xwayland glamor backend would log
an error whenever a required Wayland protocol is missing.
Those are not really errors though, more informational messages along
the glamor backend selection process.
Demote those errors to verbose messages to reduce the verbosity of
Xwayland at startup by default.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Jonas Ådahl <jadahl@gmail.com>
(cherry picked from commit 30d0d4a19be61dd7b61f5ced992cb299e6a38068)
---
hw/xwayland/xwayland-glamor-eglstream.c | 6 ++++--
hw/xwayland/xwayland-glamor-gbm.c | 2 +-
hw/xwayland/xwayland-glamor.c | 6 ++++--
3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 93d192d58..5a20b452f 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -753,12 +753,14 @@ xwl_glamor_eglstream_has_wl_interfaces(struct xwl_screen *xwl_screen)
xwl_eglstream_get(xwl_screen);
if (xwl_eglstream->display == NULL) {
- ErrorF("glamor: 'wl_eglstream_display' not supported\n");
+ LogMessageVerb(X_INFO, 3,
+ "glamor: 'wl_eglstream_display' not supported\n");
return FALSE;
}
if (xwl_eglstream->controller == NULL) {
- ErrorF("glamor: 'wl_eglstream_controller' not supported\n");
+ LogMessageVerb(X_INFO, 3,
+ "glamor: 'wl_eglstream_controller' not supported\n");
return FALSE;
}
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 466a1b052..e06b6f54b 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -835,7 +835,7 @@ xwl_glamor_gbm_has_wl_interfaces(struct xwl_screen *xwl_screen)
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
if (xwl_gbm->drm == NULL) {
- ErrorF("glamor: 'wl_drm' not supported\n");
+ LogMessageVerb(X_INFO, 3, "glamor: 'wl_drm' not supported\n");
return FALSE;
}
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index deb398f91..541d5e923 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -412,7 +412,8 @@ xwl_glamor_select_gbm_backend(struct xwl_screen *xwl_screen)
return TRUE;
}
else
- ErrorF("Missing Wayland requirements for glamor GBM backend\n");
+ LogMessageVerb(X_INFO, 3,
+ "Missing Wayland requirements for glamor GBM backend\n");
#endif
return FALSE;
@@ -428,7 +429,8 @@ xwl_glamor_select_eglstream_backend(struct xwl_screen *xwl_screen)
return TRUE;
}
else
- ErrorF("Missing Wayland requirements for glamor EGLStream backend\n");
+ LogMessageVerb(X_INFO, 3,
+ "Missing Wayland requirements for glamor EGLStream backend\n");
#endif
return FALSE;
--
2.33.1

View File

@ -1,330 +0,0 @@
From ec91c17a881eaf69c4109f050e7bb9928906c52e Mon Sep 17 00:00:00 2001
From: Erik Kurzinger <ekurzinger@nvidia.com>
Date: Fri, 12 Feb 2021 12:09:27 -0800
Subject: [PATCH xserver 02/27] xwayland: move formats and modifiers functions
to common glamor code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is preliminary work for hardware accelerated rendering with the
NVIDIA driver.
This moves the modifiers and formats functions previously only available
to the GBM backend to the common glamor code so that it can be used by
both the GBM and EGLStream backends.
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
(cherry picked from commit 400d4d0fdd55192f394e1a8273dfb2423c895ec0)
---
hw/xwayland/xwayland-glamor-gbm.c | 115 ++----------------------------
hw/xwayland/xwayland-glamor.c | 111 ++++++++++++++++++++++++++++
hw/xwayland/xwayland-glamor.h | 8 ++-
3 files changed, 123 insertions(+), 111 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 73c69727e..455b755ca 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -97,25 +97,6 @@ gbm_format_for_depth(int depth)
}
}
-static uint32_t
-wl_drm_format_for_depth(int depth)
-{
- switch (depth) {
- case 15:
- return WL_DRM_FORMAT_XRGB1555;
- case 16:
- return WL_DRM_FORMAT_RGB565;
- case 24:
- return WL_DRM_FORMAT_XRGB8888;
- case 30:
- return WL_DRM_FORMAT_ARGB2101010;
- default:
- ErrorF("unexpected depth: %d\n", depth);
- case 32:
- return WL_DRM_FORMAT_ARGB8888;
- }
-}
-
static char
is_device_path_render_node (const char *device_path)
{
@@ -214,7 +195,7 @@ xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
uint32_t num_modifiers;
uint64_t *modifiers = NULL;
- glamor_get_modifiers(screen, format, &num_modifiers, &modifiers);
+ xwl_glamor_get_modifiers(screen, format, &num_modifiers, &modifiers);
bo = gbm_bo_create_with_modifiers(xwl_gbm->gbm, width, height,
format, modifiers, num_modifiers);
free(modifiers);
@@ -277,8 +258,6 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
unsigned short width = pixmap->drawable.width;
unsigned short height = pixmap->drawable.height;
uint32_t format;
- struct xwl_format *xwl_format = NULL;
- Bool modifier_supported = FALSE;
int prime_fd;
int num_planes;
uint32_t strides[4];
@@ -317,23 +296,8 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
offsets[0] = 0;
#endif
- for (i = 0; i < xwl_screen->num_formats; i++) {
- if (xwl_screen->formats[i].format == format) {
- xwl_format = &xwl_screen->formats[i];
- break;
- }
- }
-
- if (xwl_format) {
- for (i = 0; i < xwl_format->num_modifiers; i++) {
- if (xwl_format->modifiers[i] == modifier) {
- modifier_supported = TRUE;
- break;
- }
- }
- }
-
- if (xwl_screen->dmabuf && modifier_supported) {
+ if (xwl_screen->dmabuf &&
+ xwl_glamor_is_modifier_supported(xwl_screen, format, modifier)) {
struct zwp_linux_buffer_params_v1 *params;
params = zwp_linux_dmabuf_v1_create_params(xwl_screen->dmabuf);
@@ -592,83 +556,14 @@ glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
return -1;
}
-_X_EXPORT Bool
-glamor_get_formats(ScreenPtr screen,
- CARD32 *num_formats, CARD32 **formats)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- int i;
-
- /* Explicitly zero the count as the caller may ignore the return value */
- *num_formats = 0;
-
- if (!xwl_gbm->dmabuf_capable || !xwl_screen->dmabuf)
- return FALSE;
-
- if (xwl_screen->num_formats == 0)
- return TRUE;
-
- *formats = calloc(xwl_screen->num_formats, sizeof(CARD32));
- if (*formats == NULL)
- return FALSE;
-
- for (i = 0; i < xwl_screen->num_formats; i++)
- (*formats)[i] = xwl_screen->formats[i].format;
- *num_formats = xwl_screen->num_formats;
-
- return TRUE;
-}
-
-_X_EXPORT Bool
-glamor_get_modifiers(ScreenPtr screen, uint32_t format,
- uint32_t *num_modifiers, uint64_t **modifiers)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- struct xwl_format *xwl_format = NULL;
- int i;
-
- /* Explicitly zero the count as the caller may ignore the return value */
- *num_modifiers = 0;
-
- if (!xwl_gbm->dmabuf_capable || !xwl_screen->dmabuf)
- return FALSE;
-
- if (xwl_screen->num_formats == 0)
- return TRUE;
-
- for (i = 0; i < xwl_screen->num_formats; i++) {
- if (xwl_screen->formats[i].format == format) {
- xwl_format = &xwl_screen->formats[i];
- break;
- }
- }
-
- if (!xwl_format ||
- (xwl_format->num_modifiers == 1 &&
- xwl_format->modifiers[0] == DRM_FORMAT_MOD_INVALID))
- return FALSE;
-
- *modifiers = calloc(xwl_format->num_modifiers, sizeof(uint64_t));
- if (*modifiers == NULL)
- return FALSE;
-
- for (i = 0; i < xwl_format->num_modifiers; i++)
- (*modifiers)[i] = xwl_format->modifiers[i];
- *num_modifiers = xwl_format->num_modifiers;
-
- return TRUE;
-}
-
static const dri3_screen_info_rec xwl_dri3_info = {
.version = 2,
.open = NULL,
.pixmap_from_fds = glamor_pixmap_from_fds,
.fds_from_pixmap = glamor_fds_from_pixmap,
.open_client = xwl_dri3_open_client,
- .get_formats = glamor_get_formats,
- .get_modifiers = glamor_get_modifiers,
+ .get_formats = xwl_glamor_get_formats,
+ .get_modifiers = xwl_glamor_get_modifiers,
.get_drawable_modifiers = glamor_get_drawable_modifiers,
};
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index cce0c911e..d8bf1bd5d 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -79,6 +79,117 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
xwl_screen->glamor_ctx = glamor_ctx;
}
+Bool
+xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
+ uint32_t format, uint64_t modifier)
+{
+ struct xwl_format *xwl_format = NULL;
+ int i;
+
+ for (i = 0; i < xwl_screen->num_formats; i++) {
+ if (xwl_screen->formats[i].format == format) {
+ xwl_format = &xwl_screen->formats[i];
+ break;
+ }
+ }
+
+ if (xwl_format) {
+ for (i = 0; i < xwl_format->num_modifiers; i++) {
+ if (xwl_format->modifiers[i] == modifier) {
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+uint32_t
+wl_drm_format_for_depth(int depth)
+{
+ switch (depth) {
+ case 15:
+ return WL_DRM_FORMAT_XRGB1555;
+ case 16:
+ return WL_DRM_FORMAT_RGB565;
+ case 24:
+ return WL_DRM_FORMAT_XRGB8888;
+ case 30:
+ return WL_DRM_FORMAT_ARGB2101010;
+ default:
+ ErrorF("unexpected depth: %d\n", depth);
+ case 32:
+ return WL_DRM_FORMAT_ARGB8888;
+ }
+}
+
+Bool
+xwl_glamor_get_formats(ScreenPtr screen,
+ CARD32 *num_formats, CARD32 **formats)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+ int i;
+
+ /* Explicitly zero the count as the caller may ignore the return value */
+ *num_formats = 0;
+
+ if (!xwl_screen->dmabuf)
+ return FALSE;
+
+ if (xwl_screen->num_formats == 0)
+ return TRUE;
+
+ *formats = calloc(xwl_screen->num_formats, sizeof(CARD32));
+ if (*formats == NULL)
+ return FALSE;
+
+ for (i = 0; i < xwl_screen->num_formats; i++)
+ (*formats)[i] = xwl_screen->formats[i].format;
+ *num_formats = xwl_screen->num_formats;
+
+ return TRUE;
+}
+
+Bool
+xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
+ uint32_t *num_modifiers, uint64_t **modifiers)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+ struct xwl_format *xwl_format = NULL;
+ int i;
+
+ /* Explicitly zero the count as the caller may ignore the return value */
+ *num_modifiers = 0;
+
+ if (!xwl_screen->dmabuf)
+ return FALSE;
+
+ if (xwl_screen->num_formats == 0)
+ return TRUE;
+
+ for (i = 0; i < xwl_screen->num_formats; i++) {
+ if (xwl_screen->formats[i].format == format) {
+ xwl_format = &xwl_screen->formats[i];
+ break;
+ }
+ }
+
+ if (!xwl_format ||
+ (xwl_format->num_modifiers == 1 &&
+ xwl_format->modifiers[0] == DRM_FORMAT_MOD_INVALID))
+ return FALSE;
+
+ *modifiers = calloc(xwl_format->num_modifiers, sizeof(uint64_t));
+ if (*modifiers == NULL)
+ return FALSE;
+
+ for (i = 0; i < xwl_format->num_modifiers; i++)
+ (*modifiers)[i] = xwl_format->modifiers[i];
+ *num_modifiers = xwl_format->num_modifiers;
+
+ return TRUE;
+}
+
static void
xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
uint32_t format)
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
index e017fce80..1637a0733 100644
--- a/hw/xwayland/xwayland-glamor.h
+++ b/hw/xwayland/xwayland-glamor.h
@@ -120,7 +120,13 @@ void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
Bool xwl_glamor_has_present_flip(struct xwl_screen *xwl_screen);
Bool xwl_glamor_needs_buffer_flush(struct xwl_screen *xwl_screen);
Bool xwl_glamor_needs_n_buffering(struct xwl_screen *xwl_screen);
-
+Bool xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
+ uint32_t format, uint64_t modifier);
+uint32_t wl_drm_format_for_depth(int depth);
+Bool xwl_glamor_get_formats(ScreenPtr screen,
+ CARD32 *num_formats, CARD32 **formats);
+Bool xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
+ uint32_t *num_modifiers, uint64_t **modifiers);
#ifdef XV
/* glamor Xv Adaptor */
--
2.31.1

View File

@ -0,0 +1,34 @@
From fe0c050276c09f43cc1ae80b4553db42398ca84c Mon Sep 17 00:00:00 2001
From: Povilas Kanapickas <povilas@radix.lt>
Date: Tue, 14 Dec 2021 15:00:02 +0200
Subject: [PATCH xserver 3/4] Xext: Fix out of bounds access in
SProcScreenSaverSuspend()
ZDI-CAN-14951, CVE-2021-4010
This vulnerability was discovered and the fix was suggested by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit 6c4c53010772e3cb4cb8acd54950c8eec9c00d21)
---
Xext/saver.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Xext/saver.c b/Xext/saver.c
index 1d7e3cadf..f813ba08d 100644
--- a/Xext/saver.c
+++ b/Xext/saver.c
@@ -1351,8 +1351,8 @@ SProcScreenSaverSuspend(ClientPtr client)
REQUEST(xScreenSaverSuspendReq);
swaps(&stuff->length);
- swapl(&stuff->suspend);
REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
+ swapl(&stuff->suspend);
return ProcScreenSaverSuspend(client);
}
--
2.33.1

View File

@ -1,112 +0,0 @@
From c42d3e8edc85856f95c971d5fbc5d59011c23cdc Mon Sep 17 00:00:00 2001
From: Erik Kurzinger <ekurzinger@nvidia.com>
Date: Wed, 3 Mar 2021 11:56:41 +0100
Subject: [PATCH xserver 03/27] xwayland: Add check_flip() glamor backend
function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is preliminary work for hardware accelerated rendering with the
NVIDIA driver.
This exposes a new glamor backend function, check_flip, which can be
used to control whether flipping is supported for the given pixmap.
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
(cherry picked from commit bc99dd2127f12f1aae55971c09a2792eeaa98444)
---
hw/xwayland/xwayland-glamor-eglstream.c | 7 +++++++
hw/xwayland/xwayland-glamor-gbm.c | 1 +
hw/xwayland/xwayland-glamor.c | 11 +++++++++++
hw/xwayland/xwayland-glamor.h | 6 ++++++
4 files changed, 25 insertions(+)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 9b2c2c43f..ccaa59cbe 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -633,6 +633,12 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
pixmap->refcnt++;
}
+static Bool
+xwl_glamor_eglstream_check_flip(PixmapPtr pixmap)
+{
+ return FALSE;
+}
+
static void
xwl_eglstream_display_handle_caps(void *data,
struct wl_eglstream_display *disp,
@@ -942,6 +948,7 @@ xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
xwl_screen->eglstream_backend.get_wl_buffer_for_pixmap = xwl_glamor_eglstream_get_wl_buffer_for_pixmap;
xwl_screen->eglstream_backend.post_damage = xwl_glamor_eglstream_post_damage;
xwl_screen->eglstream_backend.allow_commits = xwl_glamor_eglstream_allow_commits;
+ xwl_screen->eglstream_backend.check_flip = xwl_glamor_eglstream_check_flip;
xwl_screen->eglstream_backend.is_available = TRUE;
xwl_screen->eglstream_backend.backend_flags = XWL_EGL_BACKEND_NO_FLAG;
}
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 455b755ca..1b1d517da 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -967,6 +967,7 @@ xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
xwl_screen->gbm_backend.init_egl = xwl_glamor_gbm_init_egl;
xwl_screen->gbm_backend.init_screen = xwl_glamor_gbm_init_screen;
xwl_screen->gbm_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap;
+ xwl_screen->gbm_backend.check_flip = NULL;
xwl_screen->gbm_backend.is_available = TRUE;
xwl_screen->gbm_backend.backend_flags = XWL_EGL_BACKEND_HAS_PRESENT_FLIP |
XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH |
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index d8bf1bd5d..060471f01 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -79,6 +79,17 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
xwl_screen->glamor_ctx = glamor_ctx;
}
+Bool
+xwl_glamor_check_flip(PixmapPtr pixmap)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
+
+ if (xwl_screen->egl_backend->check_flip)
+ return xwl_screen->egl_backend->check_flip(pixmap);
+
+ return TRUE;
+}
+
Bool
xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
uint32_t format, uint64_t modifier)
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
index 1637a0733..a86b30b40 100644
--- a/hw/xwayland/xwayland-glamor.h
+++ b/hw/xwayland/xwayland-glamor.h
@@ -92,6 +92,11 @@ struct xwl_egl_backend {
* callback is optional.
*/
Bool (*allow_commits)(struct xwl_window *xwl_window);
+
+ /* Called by Xwayland to check whether the given pixmap can be
+ * presented by xwl_present_flip. If not implemented, assumed TRUE.
+ */
+ Bool (*check_flip)(PixmapPtr pixmap);
};
#ifdef XWL_HAS_GLAMOR
@@ -127,6 +132,7 @@ Bool xwl_glamor_get_formats(ScreenPtr screen,
CARD32 *num_formats, CARD32 **formats);
Bool xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
uint32_t *num_modifiers, uint64_t **modifiers);
+Bool xwl_glamor_check_flip(PixmapPtr pixmap);
#ifdef XV
/* glamor Xv Adaptor */
--
2.31.1

View File

@ -0,0 +1,42 @@
From 3206e133cb768709d32f260ac4b1bb17a46141a7 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 17 Nov 2021 13:09:58 +0100
Subject: [PATCH xserver 3/4] xwayland/glamor: Log backend selected for debug
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add (verbose) statements to trace the actual backend used with glamor.
That can be useful for debugging.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit c5d1fed9fa32244739677ec5c58ea87b261e023b)
---
hw/xwayland/xwayland-glamor.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 541d5e923..b34eafabb 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -409,6 +409,7 @@ xwl_glamor_select_gbm_backend(struct xwl_screen *xwl_screen)
if (xwl_screen->gbm_backend.is_available &&
xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->gbm_backend)) {
xwl_screen->egl_backend = &xwl_screen->gbm_backend;
+ LogMessageVerb(X_INFO, 3, "glamor: Using GBM backend\n");
return TRUE;
}
else
@@ -426,6 +427,7 @@ xwl_glamor_select_eglstream_backend(struct xwl_screen *xwl_screen)
if (xwl_screen->eglstream_backend.is_available &&
xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->eglstream_backend)) {
xwl_screen->egl_backend = &xwl_screen->eglstream_backend;
+ LogMessageVerb(X_INFO, 3, "glamor: Using EGLStream backend\n");
return TRUE;
}
else
--
2.33.1

View File

@ -0,0 +1,53 @@
From 59c977bff66de77bd93ce8853e33e1b4ca661a49 Mon Sep 17 00:00:00 2001
From: Povilas Kanapickas <povilas@radix.lt>
Date: Tue, 14 Dec 2021 15:00:03 +0200
Subject: [PATCH xserver 4/4] render: Fix out of bounds access in
SProcRenderCompositeGlyphs()
ZDI-CAN-14192, CVE-2021-4008
This vulnerability was discovered and the fix was suggested by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit ebce7e2d80e7c80e1dda60f2f0bc886f1106ba60)
---
render/render.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/render/render.c b/render/render.c
index c376090ca..456f156d4 100644
--- a/render/render.c
+++ b/render/render.c
@@ -2309,6 +2309,9 @@ SProcRenderCompositeGlyphs(ClientPtr client)
i = elt->len;
if (i == 0xff) {
+ if (buffer + 4 > end) {
+ return BadLength;
+ }
swapl((int *) buffer);
buffer += 4;
}
@@ -2319,12 +2322,18 @@ SProcRenderCompositeGlyphs(ClientPtr client)
buffer += i;
break;
case 2:
+ if (buffer + i * 2 > end) {
+ return BadLength;
+ }
while (i--) {
swaps((short *) buffer);
buffer += 2;
}
break;
case 4:
+ if (buffer + i * 4 > end) {
+ return BadLength;
+ }
while (i--) {
swapl((int *) buffer);
buffer += 4;
--
2.33.1

View File

@ -0,0 +1,64 @@
From bdc00ba749ac6cde35c025f5f6b1a5b49c1f4960 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 17 Nov 2021 09:56:52 +0100
Subject: [PATCH xserver 4/4] xwayland/eglstream: Prefer EGLstream if available
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Currently, when given the choice, Xwayland will pick the GBM backend
over the EGLstream backend if both are available, unless the command
line option “-eglstream” is specified.
The NVIDIA proprietary driver had no support for GBM until driver series
495, but starting with the driver series 495, both can be used.
But there are other requirements with the rest of the stack, typically
Mesa, egl-wayland, libglvnd as documented in the NVIDIA driver.
So if the NVIDIA driver series 495 gets installed, Xwayland will pick
the GBM backend even if EGLstream is available and may fail to render
properly.
To avoid that issue, prefer EGLstream if EGLstream and all the Wayland
interfaces are available, and fallback to GBM automatically unless
“-eglstream” was specified.
With this, the compositor, given the choice, can decide which actual
backend Xwayland would use by advertising (or not) the Wayland
"wl_eglstream_controller" interface.
This change has no impact on compositors which do not have support for
EGLstream in the first place.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit 6dd9709bd85cf5de4067887818c864220b951355)
---
hw/xwayland/xwayland-glamor.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index b34eafabb..f46b677f5 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -441,14 +441,10 @@ xwl_glamor_select_eglstream_backend(struct xwl_screen *xwl_screen)
void
xwl_glamor_select_backend(struct xwl_screen *xwl_screen, Bool use_eglstream)
{
- if (use_eglstream) {
- if (!xwl_glamor_select_eglstream_backend(xwl_screen))
+ if (!xwl_glamor_select_eglstream_backend(xwl_screen)) {
+ if (!use_eglstream)
xwl_glamor_select_gbm_backend(xwl_screen);
}
- else {
- if (!xwl_glamor_select_gbm_backend(xwl_screen))
- xwl_glamor_select_eglstream_backend(xwl_screen);
- }
}
Bool
--
2.33.1

View File

@ -1,425 +0,0 @@
From 6d1529b8d6b3e7c8bf758b670e2122a6af4d5346 Mon Sep 17 00:00:00 2001
From: Erik Kurzinger <ekurzinger@nvidia.com>
Date: Thu, 3 Dec 2020 14:57:51 -0800
Subject: [PATCH xserver 04/27] xwayland: implement pixmap_from_buffers for the
eglstream backend
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Provides an implementation for the pixmap_from_buffers DRI3 function for
xwayland's eglstream backend. This will be used by the NVIDIA GLX driver
to pass buffers from client applications to the server. These can then
be presented using the PRESENT extension.
To hopefully make this less error-prone, we also introduce a "type"
field for this struct to distinguish between xwl_pixmaps for the new
DRI3-created pixmaps and those for the existing glamor-created pixmaps.
Additionally, the patch enables wnmd present mode with the eglstream backend.
This involves creating a wl_buffer for the provided dma-buf before importing it
into EGL and passing this to the compositor so it can be scanned out directly
if possible.
Since both backends now support this present mode, the HAS_PRESENT_FLIP flag is
no longer needed, so it can be removed.
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
(cherry picked from commit 38e875904b039ec1889e7c81eb1d577a4f69b26d)
---
hw/xwayland/xwayland-glamor-eglstream.c | 202 +++++++++++++++++++++++-
hw/xwayland/xwayland-glamor-gbm.c | 3 +-
hw/xwayland/xwayland-glamor.c | 12 --
hw/xwayland/xwayland-glamor.h | 6 +-
hw/xwayland/xwayland-present.c | 5 +-
5 files changed, 204 insertions(+), 24 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index ccaa59cbe..2d8380e1f 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -37,6 +37,8 @@
#include <glamor_transfer.h>
#include <xf86drm.h>
+#include <dri3.h>
+#include <drm_fourcc.h>
#include <epoxy/egl.h>
@@ -47,6 +49,7 @@
#include "wayland-eglstream-client-protocol.h"
#include "wayland-eglstream-controller-client-protocol.h"
+#include "linux-dmabuf-unstable-v1-client-protocol.h"
struct xwl_eglstream_pending_stream {
PixmapPtr pixmap;
@@ -80,12 +83,23 @@ struct xwl_eglstream_private {
GLuint blit_is_rgba_pos;
};
+enum xwl_pixmap_type {
+ XWL_PIXMAP_EGLSTREAM, /* Pixmaps created by glamor. */
+ XWL_PIXMAP_DMA_BUF, /* Pixmaps allocated through DRI3. */
+};
+
struct xwl_pixmap {
- struct wl_buffer *buffer;
+ enum xwl_pixmap_type type;
+ /* add any new <= 4-byte member here to avoid holes on 64-bit */
struct xwl_screen *xwl_screen;
+ struct wl_buffer *buffer;
+ /* XWL_PIXMAP_EGLSTREAM. */
EGLStreamKHR stream;
EGLSurface surface;
+
+ /* XWL_PIXMAP_DMA_BUF. */
+ EGLImage image;
};
static DevPrivateKeyRec xwl_eglstream_private_key;
@@ -289,12 +303,18 @@ xwl_eglstream_unref_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
xwl_screen->egl_context);
}
- if (xwl_pixmap->surface)
+ if (xwl_pixmap->surface != EGL_NO_SURFACE)
eglDestroySurface(xwl_screen->egl_display, xwl_pixmap->surface);
- eglDestroyStreamKHR(xwl_screen->egl_display, xwl_pixmap->stream);
+ if (xwl_pixmap->stream != EGL_NO_STREAM_KHR)
+ eglDestroyStreamKHR(xwl_screen->egl_display, xwl_pixmap->stream);
+
+ if (xwl_pixmap->buffer)
+ wl_buffer_destroy(xwl_pixmap->buffer);
+
+ if (xwl_pixmap->image != EGL_NO_IMAGE_KHR)
+ eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
- wl_buffer_destroy(xwl_pixmap->buffer);
free(xwl_pixmap);
}
@@ -509,9 +529,13 @@ xwl_eglstream_create_pending_stream(struct xwl_screen *xwl_screen,
FatalError("Not enough memory to create pixmap\n");
xwl_pixmap_set_private(pixmap, xwl_pixmap);
+ xwl_pixmap->type = XWL_PIXMAP_EGLSTREAM;
+ xwl_pixmap->image = EGL_NO_IMAGE;
+
xwl_glamor_egl_make_current(xwl_screen);
xwl_pixmap->xwl_screen = xwl_screen;
+ xwl_pixmap->surface = EGL_NO_SURFACE;
xwl_pixmap->stream = eglCreateStreamKHR(xwl_screen->egl_display, NULL);
stream_fd = eglGetStreamFileDescriptorKHR(xwl_screen->egl_display,
xwl_pixmap->stream);
@@ -552,6 +576,7 @@ xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
if (xwl_pixmap) {
+ assert(xwl_pixmap->type == XWL_PIXMAP_EGLSTREAM);
if (pending) {
/* Wait for the compositor to finish connecting the consumer for
* this eglstream */
@@ -590,6 +615,8 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
};
GLint saved_vao;
+ assert(xwl_pixmap->type == XWL_PIXMAP_EGLSTREAM);
+
/* Unbind the framebuffer BEFORE binding the EGLSurface, otherwise we
* won't actually draw to it
*/
@@ -636,7 +663,7 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
static Bool
xwl_glamor_eglstream_check_flip(PixmapPtr pixmap)
{
- return FALSE;
+ return xwl_pixmap_get(pixmap)->type == XWL_PIXMAP_DMA_BUF;
}
static void
@@ -681,6 +708,9 @@ xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen,
xwl_eglstream->controller = wl_registry_bind(
wl_registry, id, &wl_eglstream_controller_interface, version);
return TRUE;
+ } else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) {
+ xwl_screen_set_dmabuf_interface(xwl_screen, id, version);
+ return TRUE;
}
/* no match */
@@ -779,6 +809,163 @@ xwl_eglstream_init_shaders(struct xwl_screen *xwl_screen)
glGetUniformLocation(xwl_eglstream->blit_prog, "is_rgba");
}
+static int
+xwl_dri3_open_client(ClientPtr client,
+ ScreenPtr screen,
+ RRProviderPtr provider,
+ int *pfd)
+{
+ /* Not supported with this backend. */
+ return BadImplementation;
+}
+
+static PixmapPtr
+xwl_dri3_pixmap_from_fds(ScreenPtr screen,
+ CARD8 num_fds, const int *fds,
+ CARD16 width, CARD16 height,
+ const CARD32 *strides, const CARD32 *offsets,
+ CARD8 depth, CARD8 bpp,
+ uint64_t modifier)
+{
+ PixmapPtr pixmap;
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+ struct xwl_pixmap *xwl_pixmap;
+ unsigned int texture;
+ EGLint image_attribs[48];
+ uint32_t mod_hi = modifier >> 32, mod_lo = modifier & 0xffffffff, format;
+ int attrib = 0, i;
+ struct zwp_linux_buffer_params_v1 *params;
+
+ format = wl_drm_format_for_depth(depth);
+ if (!xwl_glamor_is_modifier_supported(xwl_screen, format, modifier)) {
+ ErrorF("glamor: unsupported format modifier\n");
+ return NULL;
+ }
+
+ xwl_pixmap = calloc(1, sizeof (*xwl_pixmap));
+ if (!xwl_pixmap)
+ return NULL;
+ xwl_pixmap->type = XWL_PIXMAP_DMA_BUF;
+ xwl_pixmap->xwl_screen = xwl_screen;
+
+ xwl_pixmap->buffer = NULL;
+ xwl_pixmap->stream = EGL_NO_STREAM_KHR;
+ xwl_pixmap->surface = EGL_NO_SURFACE;
+
+ params = zwp_linux_dmabuf_v1_create_params(xwl_screen->dmabuf);
+ for (i = 0; i < num_fds; i++) {
+ zwp_linux_buffer_params_v1_add(params, fds[i], i,
+ offsets[i], strides[i],
+ mod_hi, mod_lo);
+ }
+ xwl_pixmap->buffer =
+ zwp_linux_buffer_params_v1_create_immed(params, width, height,
+ format, 0);
+ zwp_linux_buffer_params_v1_destroy(params);
+
+
+ image_attribs[attrib++] = EGL_WIDTH;
+ image_attribs[attrib++] = width;
+ image_attribs[attrib++] = EGL_HEIGHT;
+ image_attribs[attrib++] = height;
+ image_attribs[attrib++] = EGL_LINUX_DRM_FOURCC_EXT;
+ image_attribs[attrib++] = drm_format_for_depth(depth, bpp);
+
+ if (num_fds > 0) {
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_FD_EXT;
+ image_attribs[attrib++] = fds[0];
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
+ image_attribs[attrib++] = offsets[0];
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
+ image_attribs[attrib++] = strides[0];
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
+ image_attribs[attrib++] = mod_hi;
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
+ image_attribs[attrib++] = mod_lo;
+ }
+ if (num_fds > 1) {
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_FD_EXT;
+ image_attribs[attrib++] = fds[1];
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
+ image_attribs[attrib++] = offsets[1];
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
+ image_attribs[attrib++] = strides[1];
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
+ image_attribs[attrib++] = mod_hi;
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
+ image_attribs[attrib++] = mod_lo;
+ }
+ if (num_fds > 2) {
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_FD_EXT;
+ image_attribs[attrib++] = fds[2];
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
+ image_attribs[attrib++] = offsets[2];
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
+ image_attribs[attrib++] = strides[2];
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
+ image_attribs[attrib++] = mod_hi;
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
+ image_attribs[attrib++] = mod_lo;
+ }
+ if (num_fds > 3) {
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_FD_EXT;
+ image_attribs[attrib++] = fds[3];
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT;
+ image_attribs[attrib++] = offsets[3];
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
+ image_attribs[attrib++] = strides[3];
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT;
+ image_attribs[attrib++] = mod_hi;