Compare commits
No commits in common. "imports/c8/xorg-x11-server-Xwayland-21.1.1-6.el8" and "c8-beta" have entirely different histories.
imports/c8
...
c8-beta
|
@ -1 +1 @@
|
|||
SOURCES/xwayland-21.1.1.tar.xz
|
||||
SOURCES/xwayland-21.1.3.tar.xz
|
||||
|
|
|
@ -1 +1 @@
|
|||
4eb5e22033c0c80c35480c9466e8041e914cac3a SOURCES/xwayland-21.1.1.tar.xz
|
||||
ae980a7deeb7cad9f3cd253f3b1ddca5bb26aafa SOURCES/xwayland-21.1.3.tar.xz
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
From 19e9f199950aaa4b9b7696936d1b067475da999c Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 28 Nov 2023 15:19:04 +1000
|
||||
Subject: [PATCH xserver] Xi: allocate enough XkbActions for our buttons
|
||||
|
||||
button->xkb_acts is supposed to be an array sufficiently large for all
|
||||
our buttons, not just a single XkbActions struct. Allocating
|
||||
insufficient memory here means when we memcpy() later in
|
||||
XkbSetDeviceInfo we write into memory that wasn't ours to begin with,
|
||||
leading to the usual security ooopsiedaisies.
|
||||
|
||||
CVE-2023-6377, ZDI-CAN-22412, ZDI-CAN-22413
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
(cherry picked from commit 0c1a93d319558fe3ab2d94f51d174b4f93810afd)
|
||||
---
|
||||
Xi/exevents.c | 12 ++++++------
|
||||
dix/devices.c | 10 ++++++++++
|
||||
2 files changed, 16 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/Xi/exevents.c b/Xi/exevents.c
|
||||
index dcd4efb3b..54ea11a93 100644
|
||||
--- a/Xi/exevents.c
|
||||
+++ b/Xi/exevents.c
|
||||
@@ -611,13 +611,13 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
|
||||
}
|
||||
|
||||
if (from->button->xkb_acts) {
|
||||
- if (!to->button->xkb_acts) {
|
||||
- to->button->xkb_acts = calloc(1, sizeof(XkbAction));
|
||||
- if (!to->button->xkb_acts)
|
||||
- FatalError("[Xi] not enough memory for xkb_acts.\n");
|
||||
- }
|
||||
+ size_t maxbuttons = max(to->button->numButtons, from->button->numButtons);
|
||||
+ to->button->xkb_acts = xnfreallocarray(to->button->xkb_acts,
|
||||
+ maxbuttons,
|
||||
+ sizeof(XkbAction));
|
||||
+ memset(to->button->xkb_acts, 0, maxbuttons * sizeof(XkbAction));
|
||||
memcpy(to->button->xkb_acts, from->button->xkb_acts,
|
||||
- sizeof(XkbAction));
|
||||
+ from->button->numButtons * sizeof(XkbAction));
|
||||
}
|
||||
else {
|
||||
free(to->button->xkb_acts);
|
||||
diff --git a/dix/devices.c b/dix/devices.c
|
||||
index 7150734a5..20fef1692 100644
|
||||
--- a/dix/devices.c
|
||||
+++ b/dix/devices.c
|
||||
@@ -2530,6 +2530,8 @@ RecalculateMasterButtons(DeviceIntPtr slave)
|
||||
|
||||
if (master->button && master->button->numButtons != maxbuttons) {
|
||||
int i;
|
||||
+ int last_num_buttons = master->button->numButtons;
|
||||
+
|
||||
DeviceChangedEvent event = {
|
||||
.header = ET_Internal,
|
||||
.type = ET_DeviceChanged,
|
||||
@@ -2540,6 +2542,14 @@ RecalculateMasterButtons(DeviceIntPtr slave)
|
||||
};
|
||||
|
||||
master->button->numButtons = maxbuttons;
|
||||
+ if (last_num_buttons < maxbuttons) {
|
||||
+ master->button->xkb_acts = xnfreallocarray(master->button->xkb_acts,
|
||||
+ maxbuttons,
|
||||
+ sizeof(XkbAction));
|
||||
+ memset(&master->button->xkb_acts[last_num_buttons],
|
||||
+ 0,
|
||||
+ (maxbuttons - last_num_buttons) * sizeof(XkbAction));
|
||||
+ }
|
||||
|
||||
memcpy(&event.buttons.names, master->button->labels, maxbuttons *
|
||||
sizeof(Atom));
|
||||
--
|
||||
2.43.0
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
From 8660dd164882ce5fc1f274427e2ff3dc020d6273 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Wed, 25 Jan 2023 11:41:40 +1000
|
||||
Subject: [PATCH xserver] Xi: fix potential use-after-free in
|
||||
DeepCopyPointerClasses
|
||||
|
||||
CVE-2023-0494, ZDI-CAN-19596
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
(cherry picked from commit 0ba6d8c37071131a49790243cdac55392ecf71ec)
|
||||
---
|
||||
Xi/exevents.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Xi/exevents.c b/Xi/exevents.c
|
||||
index 217baa956..dcd4efb3b 100644
|
||||
--- a/Xi/exevents.c
|
||||
+++ b/Xi/exevents.c
|
||||
@@ -619,8 +619,10 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
|
||||
memcpy(to->button->xkb_acts, from->button->xkb_acts,
|
||||
sizeof(XkbAction));
|
||||
}
|
||||
- else
|
||||
+ else {
|
||||
free(to->button->xkb_acts);
|
||||
+ to->button->xkb_acts = NULL;
|
||||
+ }
|
||||
|
||||
memcpy(to->button->labels, from->button->labels,
|
||||
from->button->numButtons * sizeof(Atom));
|
||||
--
|
||||
2.39.1
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
From 1e8478455458e998dd366d2cd23d2aeab2bdeee5 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 3 Oct 2023 11:53:05 +1000
|
||||
Subject: [PATCH xserver] Xi/randr: fix handling of PropModeAppend/Prepend
|
||||
|
||||
The handling of appending/prepending properties was incorrect, with at
|
||||
least two bugs: the property length was set to the length of the new
|
||||
part only, i.e. appending or prepending N elements to a property with P
|
||||
existing elements always resulted in the property having N elements
|
||||
instead of N + P.
|
||||
|
||||
Second, when pre-pending a value to a property, the offset for the old
|
||||
values was incorrect, leaving the new property with potentially
|
||||
uninitalized values and/or resulting in OOB memory writes.
|
||||
For example, prepending a 3 element value to a 5 element property would
|
||||
result in this 8 value array:
|
||||
[N, N, N, ?, ?, P, P, P ] P, P
|
||||
^OOB write
|
||||
|
||||
The XI2 code is a copy/paste of the RandR code, so the bug exists in
|
||||
both.
|
||||
|
||||
CVE-2023-5367, ZDI-CAN-22153
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
(cherry picked from commit 541ab2ecd41d4d8689e71855d93e492bc554719a)
|
||||
---
|
||||
Xi/xiproperty.c | 4 ++--
|
||||
randr/rrproperty.c | 4 ++--
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
|
||||
index 066ba21fba..d315f04d0e 100644
|
||||
--- a/Xi/xiproperty.c
|
||||
+++ b/Xi/xiproperty.c
|
||||
@@ -730,7 +730,7 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
|
||||
XIDestroyDeviceProperty(prop);
|
||||
return BadAlloc;
|
||||
}
|
||||
- new_value.size = len;
|
||||
+ new_value.size = total_len;
|
||||
new_value.type = type;
|
||||
new_value.format = format;
|
||||
|
||||
@@ -747,7 +747,7 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
|
||||
case PropModePrepend:
|
||||
new_data = new_value.data;
|
||||
old_data = (void *) (((char *) new_value.data) +
|
||||
- (prop_value->size * size_in_bytes));
|
||||
+ (len * size_in_bytes));
|
||||
break;
|
||||
}
|
||||
if (new_data)
|
||||
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
|
||||
index c2fb9585c6..25469f57b2 100644
|
||||
--- a/randr/rrproperty.c
|
||||
+++ b/randr/rrproperty.c
|
||||
@@ -209,7 +209,7 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
|
||||
RRDestroyOutputProperty(prop);
|
||||
return BadAlloc;
|
||||
}
|
||||
- new_value.size = len;
|
||||
+ new_value.size = total_len;
|
||||
new_value.type = type;
|
||||
new_value.format = format;
|
||||
|
||||
@@ -226,7 +226,7 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
|
||||
case PropModePrepend:
|
||||
new_data = new_value.data;
|
||||
old_data = (void *) (((char *) new_value.data) +
|
||||
- (prop_value->size * size_in_bytes));
|
||||
+ (len * size_in_bytes));
|
||||
break;
|
||||
}
|
||||
if (new_data)
|
||||
--
|
||||
2.41.0
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
From 8dba686dc277d6d262ad0c77b4632a5b276697ba Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 29 Nov 2022 12:55:45 +1000
|
||||
Subject: [PATCH xserver 1/7] Xtest: disallow GenericEvents in
|
||||
XTestSwapFakeInput
|
||||
|
||||
XTestSwapFakeInput assumes all events in this request are
|
||||
sizeof(xEvent) and iterates through these in 32-byte increments.
|
||||
However, a GenericEvent may be of arbitrary length longer than 32 bytes,
|
||||
so any GenericEvent in this list would result in subsequent events to be
|
||||
misparsed.
|
||||
|
||||
Additional, the swapped event is written into a stack-allocated struct
|
||||
xEvent (size 32 bytes). For any GenericEvent longer than 32 bytes,
|
||||
swapping the event may thus smash the stack like an avocado on toast.
|
||||
|
||||
Catch this case early and return BadValue for any GenericEvent.
|
||||
Which is what would happen in unswapped setups anyway since XTest
|
||||
doesn't support GenericEvent.
|
||||
|
||||
CVE-2022-46340, ZDI-CAN 19265
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
---
|
||||
Xext/xtest.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Xext/xtest.c b/Xext/xtest.c
|
||||
index bf27eb590b..2985a4ce6e 100644
|
||||
--- a/Xext/xtest.c
|
||||
+++ b/Xext/xtest.c
|
||||
@@ -502,10 +502,11 @@ XTestSwapFakeInput(ClientPtr client, xReq * req)
|
||||
|
||||
nev = ((req->length << 2) - sizeof(xReq)) / sizeof(xEvent);
|
||||
for (ev = (xEvent *) &req[1]; --nev >= 0; ev++) {
|
||||
+ int evtype = ev->u.u.type & 0x177;
|
||||
/* Swap event */
|
||||
- proc = EventSwapVector[ev->u.u.type & 0177];
|
||||
+ proc = EventSwapVector[evtype];
|
||||
/* no swapping proc; invalid event type? */
|
||||
- if (!proc || proc == NotImplemented) {
|
||||
+ if (!proc || proc == NotImplemented || evtype == GenericEvent) {
|
||||
client->errorValue = ev->u.u.type;
|
||||
return BadValue;
|
||||
}
|
||||
--
|
||||
2.38.1
|
|
@ -0,0 +1,42 @@
|
|||
From 26ef545b3502f61ca722a7a3373507e88ef64110 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Mon, 13 Mar 2023 11:08:47 +0100
|
||||
Subject: [PATCH xserver] composite: Fix use-after-free of the COW
|
||||
|
||||
ZDI-CAN-19866/CVE-2023-1393
|
||||
|
||||
If a client explicitly destroys the compositor overlay window (aka COW),
|
||||
we would leave a dangling pointer to that window in the CompScreen
|
||||
structure, which will trigger a use-after-free later.
|
||||
|
||||
Make sure to clear the CompScreen pointer to the COW when the latter gets
|
||||
destroyed explicitly by the client.
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Adam Jackson <ajax@redhat.com>
|
||||
---
|
||||
composite/compwindow.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/composite/compwindow.c b/composite/compwindow.c
|
||||
index 4e2494b86..b30da589e 100644
|
||||
--- a/composite/compwindow.c
|
||||
+++ b/composite/compwindow.c
|
||||
@@ -620,6 +620,11 @@ compDestroyWindow(WindowPtr pWin)
|
||||
ret = (*pScreen->DestroyWindow) (pWin);
|
||||
cs->DestroyWindow = pScreen->DestroyWindow;
|
||||
pScreen->DestroyWindow = compDestroyWindow;
|
||||
+
|
||||
+ /* Did we just destroy the overlay window? */
|
||||
+ if (pWin == cs->pOverlayWin)
|
||||
+ cs->pOverlayWin = NULL;
|
||||
+
|
||||
/* compCheckTree (pWin->drawable.pScreen); can't check -- tree isn't good*/
|
||||
return ret;
|
||||
}
|
||||
--
|
||||
2.40.0
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
From b5cb27032d3e486ba84a491e1420e85171c4c0a3 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Thu, 14 Dec 2023 11:29:49 +1000
|
||||
Subject: [PATCH xserver 1/9] dix: allocate enough space for logical button
|
||||
maps
|
||||
|
||||
Both DeviceFocusEvent and the XIQueryPointer reply contain a bit for
|
||||
each logical button currently down. Since buttons can be arbitrarily mapped
|
||||
to anything up to 255 make sure we have enough bits for the maximum mapping.
|
||||
|
||||
CVE-2023-6816, ZDI-CAN-22664, ZDI-CAN-22665
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
(cherry picked from commit 9e2ecb2af8302dedc49cb6a63ebe063c58a9e7e3)
|
||||
---
|
||||
Xi/xiquerypointer.c | 3 +--
|
||||
dix/enterleave.c | 5 +++--
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Xi/xiquerypointer.c b/Xi/xiquerypointer.c
|
||||
index 5b77b1a44..2b05ac5f3 100644
|
||||
--- a/Xi/xiquerypointer.c
|
||||
+++ b/Xi/xiquerypointer.c
|
||||
@@ -149,8 +149,7 @@ ProcXIQueryPointer(ClientPtr client)
|
||||
if (pDev->button) {
|
||||
int i;
|
||||
|
||||
- rep.buttons_len =
|
||||
- bytes_to_int32(bits_to_bytes(pDev->button->numButtons));
|
||||
+ rep.buttons_len = bytes_to_int32(bits_to_bytes(256)); /* button map up to 255 */
|
||||
rep.length += rep.buttons_len;
|
||||
buttons = calloc(rep.buttons_len, 4);
|
||||
if (!buttons)
|
||||
diff --git a/dix/enterleave.c b/dix/enterleave.c
|
||||
index 867ec7436..ded8679d7 100644
|
||||
--- a/dix/enterleave.c
|
||||
+++ b/dix/enterleave.c
|
||||
@@ -784,8 +784,9 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
|
||||
|
||||
mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER);
|
||||
|
||||
- /* XI 2 event */
|
||||
- btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0;
|
||||
+ /* XI 2 event contains the logical button map - maps are CARD8
|
||||
+ * so we need 256 bits for the possibly maximum mapping */
|
||||
+ btlen = (mouse->button) ? bits_to_bytes(256) : 0;
|
||||
btlen = bytes_to_int32(btlen);
|
||||
len = sizeof(xXIFocusInEvent) + btlen * 4;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
From b98fc07d3442a289c6bef82df50dd0a2d01de71a Mon Sep 17 00:00:00 2001
|
||||
From: Adam Jackson <ajax@redhat.com>
|
||||
Date: Thu, 2 Feb 2023 12:26:27 -0500
|
||||
Subject: [PATCH xserver] present: Send a PresentConfigureNotify event for
|
||||
destroyed windows
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This enables fixing a deadlock case on the client side, where the client
|
||||
ends up blocked waiting for a Present event that will never come because
|
||||
the window was destroyed. The new PresentWindowDestroyed flag allows the
|
||||
client to avoid blocking indefinitely.
|
||||
|
||||
Signed-off-by: Adam Jackson <ajax@redhat.com>
|
||||
See-also: https://gitlab.freedesktop.org/mesa/mesa/-/issues/116
|
||||
See-also: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6685
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
(cherry picked from commit 462b06033e66a32308d940eb5fc47f5e4c914dc0)
|
||||
---
|
||||
present/present_event.c | 5 +++--
|
||||
present/present_priv.h | 7 ++++++-
|
||||
present/present_screen.c | 11 ++++++++++-
|
||||
3 files changed, 19 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/present/present_event.c b/present/present_event.c
|
||||
index 435b26b70..849732dc8 100644
|
||||
--- a/present/present_event.c
|
||||
+++ b/present/present_event.c
|
||||
@@ -102,7 +102,8 @@ present_event_swap(xGenericEvent *from, xGenericEvent *to)
|
||||
}
|
||||
|
||||
void
|
||||
-present_send_config_notify(WindowPtr window, int x, int y, int w, int h, int bw, WindowPtr sibling)
|
||||
+present_send_config_notify(WindowPtr window, int x, int y, int w, int h,
|
||||
+ int bw, WindowPtr sibling, CARD32 flags)
|
||||
{
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
|
||||
@@ -122,7 +123,7 @@ present_send_config_notify(WindowPtr window, int x, int y, int w, int h, int bw,
|
||||
.off_y = 0,
|
||||
.pixmap_width = w,
|
||||
.pixmap_height = h,
|
||||
- .pixmap_flags = 0
|
||||
+ .pixmap_flags = flags
|
||||
};
|
||||
present_event_ptr event;
|
||||
|
||||
diff --git a/present/present_priv.h b/present/present_priv.h
|
||||
index 6ebd009a2..4ad729864 100644
|
||||
--- a/present/present_priv.h
|
||||
+++ b/present/present_priv.h
|
||||
@@ -43,6 +43,11 @@
|
||||
#define DebugPresent(x)
|
||||
#endif
|
||||
|
||||
+/* XXX this belongs in presentproto */
|
||||
+#ifndef PresentWindowDestroyed
|
||||
+#define PresentWindowDestroyed (1 << 0)
|
||||
+#endif
|
||||
+
|
||||
extern int present_request;
|
||||
|
||||
extern DevPrivateKeyRec present_screen_private_key;
|
||||
@@ -307,7 +312,7 @@ void
|
||||
present_free_events(WindowPtr window);
|
||||
|
||||
void
|
||||
-present_send_config_notify(WindowPtr window, int x, int y, int w, int h, int bw, WindowPtr sibling);
|
||||
+present_send_config_notify(WindowPtr window, int x, int y, int w, int h, int bw, WindowPtr sibling, CARD32 flags);
|
||||
|
||||
void
|
||||
present_send_complete_notify(WindowPtr window, CARD8 kind, CARD8 mode, CARD32 serial, uint64_t ust, uint64_t msc);
|
||||
diff --git a/present/present_screen.c b/present/present_screen.c
|
||||
index 15684eda4..2c29aafd2 100644
|
||||
--- a/present/present_screen.c
|
||||
+++ b/present/present_screen.c
|
||||
@@ -93,6 +93,15 @@ present_destroy_window(WindowPtr window)
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
|
||||
+ present_send_config_notify(window,
|
||||
+ window->drawable.x,
|
||||
+ window->drawable.y,
|
||||
+ window->drawable.width,
|
||||
+ window->drawable.height,
|
||||
+ window->borderWidth,
|
||||
+ window->nextSib,
|
||||
+ PresentWindowDestroyed);
|
||||
+
|
||||
if (window_priv) {
|
||||
present_clear_window_notifies(window);
|
||||
present_free_events(window);
|
||||
@@ -123,7 +132,7 @@ present_config_notify(WindowPtr window,
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
|
||||
- present_send_config_notify(window, x, y, w, h, bw, sibling);
|
||||
+ present_send_config_notify(window, x, y, w, h, bw, sibling, 0);
|
||||
|
||||
unwrap(screen_priv, screen, ConfigNotify);
|
||||
if (screen->ConfigNotify)
|
||||
--
|
||||
2.40.0
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
From aaf854fb25541380cc38a221c15f0e8372f48872 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Mon, 27 Nov 2023 16:27:49 +1000
|
||||
Subject: [PATCH xserver] randr: avoid integer truncation in length check of
|
||||
ProcRRChange*Property
|
||||
|
||||
Affected are ProcRRChangeProviderProperty and ProcRRChangeOutputProperty.
|
||||
See also xserver@8f454b79 where this same bug was fixed for the core
|
||||
protocol and XI.
|
||||
|
||||
This fixes an OOB read and the resulting information disclosure.
|
||||
|
||||
Length calculation for the request was clipped to a 32-bit integer. With
|
||||
the correct stuff->nUnits value the expected request size was
|
||||
truncated, passing the REQUEST_FIXED_SIZE check.
|
||||
|
||||
The server then proceeded with reading at least stuff->num_items bytes
|
||||
(depending on stuff->format) from the request and stuffing whatever it
|
||||
finds into the property. In the process it would also allocate at least
|
||||
stuff->nUnits bytes, i.e. 4GB.
|
||||
|
||||
CVE-2023-6478, ZDI-CAN-22561
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
(cherry picked from commit 14f480010a93ff962fef66a16412fafff81ad632)
|
||||
---
|
||||
randr/rrproperty.c | 2 +-
|
||||
randr/rrproviderproperty.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
|
||||
index 25469f57b..c4fef8a1f 100644
|
||||
--- a/randr/rrproperty.c
|
||||
+++ b/randr/rrproperty.c
|
||||
@@ -530,7 +530,7 @@ ProcRRChangeOutputProperty(ClientPtr client)
|
||||
char format, mode;
|
||||
unsigned long len;
|
||||
int sizeInBytes;
|
||||
- int totalSize;
|
||||
+ uint64_t totalSize;
|
||||
int err;
|
||||
|
||||
REQUEST_AT_LEAST_SIZE(xRRChangeOutputPropertyReq);
|
||||
diff --git a/randr/rrproviderproperty.c b/randr/rrproviderproperty.c
|
||||
index b79c17f9b..90c5a9a93 100644
|
||||
--- a/randr/rrproviderproperty.c
|
||||
+++ b/randr/rrproviderproperty.c
|
||||
@@ -498,7 +498,7 @@ ProcRRChangeProviderProperty(ClientPtr client)
|
||||
char format, mode;
|
||||
unsigned long len;
|
||||
int sizeInBytes;
|
||||
- int totalSize;
|
||||
+ uint64_t totalSize;
|
||||
int err;
|
||||
|
||||
REQUEST_AT_LEAST_SIZE(xRRChangeProviderPropertyReq);
|
||||
--
|
||||
2.43.0
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
From 18f91b950e22c2a342a4fbc55e9ddf7534a707d2 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Wed, 13 Jul 2022 11:23:09 +1000
|
||||
Subject: [PATCH xserver] xkb: fix some possible memleaks in XkbGetKbdByName
|
||||
|
||||
GetComponentByName returns an allocated string, so let's free that if we
|
||||
fail somewhere.
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
---
|
||||
xkb/xkb.c | 26 ++++++++++++++++++++------
|
||||
1 file changed, 20 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/xkb/xkb.c b/xkb/xkb.c
|
||||
index 4692895db..b79a269e3 100644
|
||||
--- a/xkb/xkb.c
|
||||
+++ b/xkb/xkb.c
|
||||
@@ -5935,18 +5935,32 @@ ProcXkbGetKbdByName(ClientPtr client)
|
||||
xkb = dev->key->xkbInfo->desc;
|
||||
status = Success;
|
||||
str = (unsigned char *) &stuff[1];
|
||||
- if (GetComponentSpec(&str, TRUE, &status)) /* keymap, unsupported */
|
||||
- return BadMatch;
|
||||
+ {
|
||||
+ char *keymap = GetComponentSpec(&str, TRUE, &status); /* keymap, unsupported */
|
||||
+ if (keymap) {
|
||||
+ free(keymap);
|
||||
+ return BadMatch;
|
||||
+ }
|
||||
+ }
|
||||
names.keycodes = GetComponentSpec(&str, TRUE, &status);
|
||||
names.types = GetComponentSpec(&str, TRUE, &status);
|
||||
names.compat = GetComponentSpec(&str, TRUE, &status);
|
||||
names.symbols = GetComponentSpec(&str, TRUE, &status);
|
||||
names.geometry = GetComponentSpec(&str, TRUE, &status);
|
||||
- if (status != Success)
|
||||
+ if (status == Success) {
|
||||
+ len = str - ((unsigned char *) stuff);
|
||||
+ if ((XkbPaddedSize(len) / 4) != stuff->length)
|
||||
+ status = BadLength;
|
||||
+ }
|
||||
+
|
||||
+ if (status != Success) {
|
||||
+ free(names.keycodes);
|
||||
+ free(names.types);
|
||||
+ free(names.compat);
|
||||
+ free(names.symbols);
|
||||
+ free(names.geometry);
|
||||
return status;
|
||||
- len = str - ((unsigned char *) stuff);
|
||||
- if ((XkbPaddedSize(len) / 4) != stuff->length)
|
||||
- return BadLength;
|
||||
+ }
|
||||
|
||||
CHK_MASK_LEGAL(0x01, stuff->want, XkbGBN_AllComponentsMask);
|
||||
CHK_MASK_LEGAL(0x02, stuff->need, XkbGBN_AllComponentsMask);
|
||||
--
|
||||
2.38.1
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
From 11beef0b7f1ed290348e45618e5fa0d2bffcb72e Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 5 Jul 2022 12:06:20 +1000
|
||||
Subject: [PATCH xserver] xkb: proof GetCountedString against request length
|
||||
attacks
|
||||
|
||||
GetCountedString did a check for the whole string to be within the
|
||||
request buffer but not for the initial 2 bytes that contain the length
|
||||
field. A swapped client could send a malformed request to trigger a
|
||||
swaps() on those bytes, writing into random memory.
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
---
|
||||
xkb/xkb.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/xkb/xkb.c b/xkb/xkb.c
|
||||
index f42f59ef3..1841cff26 100644
|
||||
--- a/xkb/xkb.c
|
||||
+++ b/xkb/xkb.c
|
||||
@@ -5137,6 +5137,11 @@ _GetCountedString(char **wire_inout, ClientPtr client, char **str)
|
||||
CARD16 len;
|
||||
|
||||
wire = *wire_inout;
|
||||
+
|
||||
+ if (client->req_len <
|
||||
+ bytes_to_int32(wire + 2 - (char *) client->requestBuffer))
|
||||
+ return BadValue;
|
||||
+
|
||||
len = *(CARD16 *) wire;
|
||||
if (client->swapped) {
|
||||
swaps(&len);
|
||||
--
|
||||
2.38.1
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
From c9b379ec5a1a34692af06056925bd0fc5f809713 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 5 Jul 2022 12:40:47 +1000
|
||||
Subject: [PATCH xserver 1/3] xkb: switch to array index loops to moving
|
||||
pointers
|
||||
|
||||
Most similar loops here use a pointer that advances with each loop
|
||||
iteration, let's do the same here for consistency.
|
||||
|
||||
No functional changes.
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
(cherry picked from commit f1070c01d616c5f21f939d5ebc533738779451ac)
|
||||
---
|
||||
xkb/xkb.c | 20 ++++++++++----------
|
||||
1 file changed, 10 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/xkb/xkb.c b/xkb/xkb.c
|
||||
index d056c698c..684394d77 100644
|
||||
--- a/xkb/xkb.c
|
||||
+++ b/xkb/xkb.c
|
||||
@@ -5372,16 +5372,16 @@ _CheckSetSections(XkbGeometryPtr geom,
|
||||
row->left = rWire->left;
|
||||
row->vertical = rWire->vertical;
|
||||
kWire = (xkbKeyWireDesc *) &rWire[1];
|
||||
- for (k = 0; k < rWire->nKeys; k++) {
|
||||
+ for (k = 0; k < rWire->nKeys; k++, kWire++) {
|
||||
XkbKeyPtr key;
|
||||
|
||||
key = XkbAddGeomKey(row);
|
||||
if (!key)
|
||||
return BadAlloc;
|
||||
- memcpy(key->name.name, kWire[k].name, XkbKeyNameLength);
|
||||
- key->gap = kWire[k].gap;
|
||||
- key->shape_ndx = kWire[k].shapeNdx;
|
||||
- key->color_ndx = kWire[k].colorNdx;
|
||||
+ memcpy(key->name.name, kWire->name, XkbKeyNameLength);
|
||||
+ key->gap = kWire->gap;
|
||||
+ key->shape_ndx = kWire->shapeNdx;
|
||||
+ key->color_ndx = kWire->colorNdx;
|
||||
if (key->shape_ndx >= geom->num_shapes) {
|
||||
client->errorValue = _XkbErrCode3(0x10, key->shape_ndx,
|
||||
geom->num_shapes);
|
||||
@@ -5393,7 +5393,7 @@ _CheckSetSections(XkbGeometryPtr geom,
|
||||
return BadMatch;
|
||||
}
|
||||
}
|
||||
- rWire = (xkbRowWireDesc *) &kWire[rWire->nKeys];
|
||||
+ rWire = (xkbRowWireDesc *)kWire;
|
||||
}
|
||||
wire = (char *) rWire;
|
||||
if (sWire->nDoodads > 0) {
|
||||
@@ -5458,16 +5458,16 @@ _CheckSetShapes(XkbGeometryPtr geom,
|
||||
return BadAlloc;
|
||||
ol->corner_radius = olWire->cornerRadius;
|
||||
ptWire = (xkbPointWireDesc *) &olWire[1];
|
||||
- for (p = 0, pt = ol->points; p < olWire->nPoints; p++, pt++) {
|
||||
- pt->x = ptWire[p].x;
|
||||
- pt->y = ptWire[p].y;
|
||||
+ for (p = 0, pt = ol->points; p < olWire->nPoints; p++, pt++, ptWire++) {
|
||||
+ pt->x = ptWire->x;
|
||||
+ pt->y = ptWire->y;
|
||||
if (client->swapped) {
|
||||
swaps(&pt->x);
|
||||
swaps(&pt->y);
|
||||
}
|
||||
}
|
||||
ol->num_points = olWire->nPoints;
|
||||
- olWire = (xkbOutlineWireDesc *) (&ptWire[olWire->nPoints]);
|
||||
+ olWire = (xkbOutlineWireDesc *)ptWire;
|
||||
}
|
||||
if (shapeWire->primaryNdx != XkbNoShape)
|
||||
shape->primary = &shape->outlines[shapeWire->primaryNdx];
|
||||
--
|
||||
2.36.1
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
From c5ff57676698f19ed3a1402aef58a15552e32d27 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 29 Nov 2022 13:24:00 +1000
|
||||
Subject: [PATCH xserver 2/7] Xi: return an error from XI property changes if
|
||||
verification failed
|
||||
|
||||
Both ProcXChangeDeviceProperty and ProcXIChangeProperty checked the
|
||||
property for validity but didn't actually return the potential error.
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
---
|
||||
Xi/xiproperty.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
|
||||
index a36f7d61df..68c362c628 100644
|
||||
--- a/Xi/xiproperty.c
|
||||
+++ b/Xi/xiproperty.c
|
||||
@@ -902,6 +902,8 @@ ProcXChangeDeviceProperty(ClientPtr client)
|
||||
|
||||
rc = check_change_property(client, stuff->property, stuff->type,
|
||||
stuff->format, stuff->mode, stuff->nUnits);
|
||||
+ if (rc != Success)
|
||||
+ return rc;
|
||||
|
||||
len = stuff->nUnits;
|
||||
if (len > (bytes_to_int32(0xffffffff - sizeof(xChangeDevicePropertyReq))))
|
||||
@@ -1141,6 +1143,9 @@ ProcXIChangeProperty(ClientPtr client)
|
||||
|
||||
rc = check_change_property(client, stuff->property, stuff->type,
|
||||
stuff->format, stuff->mode, stuff->num_items);
|
||||
+ if (rc != Success)
|
||||
+ return rc;
|
||||
+
|
||||
len = stuff->num_items;
|
||||
if (len > bytes_to_int32(0xffffffff - sizeof(xXIChangePropertyReq)))
|
||||
return BadLength;
|
||||
--
|
||||
2.38.1
|
|
@ -0,0 +1,86 @@
|
|||
From 9105be1c51d6973dc8d7806108349bc152029ec5 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Mon, 18 Dec 2023 14:27:50 +1000
|
||||
Subject: [PATCH xserver 2/9] dix: Allocate sufficient xEvents for our
|
||||
DeviceStateNotify
|
||||
|
||||
If a device has both a button class and a key class and numButtons is
|
||||
zero, we can get an OOB write due to event under-allocation.
|
||||
|
||||
This function seems to assume a device has either keys or buttons, not
|
||||
both. It has two virtually identical code paths, both of which assume
|
||||
they're applying to the first event in the sequence.
|
||||
|
||||
A device with both a key and button class triggered a logic bug - only
|
||||
one xEvent was allocated but the deviceStateNotify pointer was pushed on
|
||||
once per type. So effectively this logic code:
|
||||
|
||||
int count = 1;
|
||||
if (button && nbuttons > 32) count++;
|
||||
if (key && nbuttons > 0) count++;
|
||||
if (key && nkeys > 32) count++; // this is basically always true
|
||||
// count is at 2 for our keys + zero button device
|
||||
|
||||
ev = alloc(count * sizeof(xEvent));
|
||||
FixDeviceStateNotify(ev);
|
||||
if (button)
|
||||
FixDeviceStateNotify(ev++);
|
||||
if (key)
|
||||
FixDeviceStateNotify(ev++); // santa drops into the wrong chimney here
|
||||
|
||||
If the device has more than 3 valuators, the OOB is pushed back - we're
|
||||
off by one so it will happen when the last deviceValuator event is
|
||||
written instead.
|
||||
|
||||
Fix this by allocating the maximum number of events we may allocate.
|
||||
Note that the current behavior is not protocol-correct anyway, this
|
||||
patch fixes only the allocation issue.
|
||||
|
||||
Note that this issue does not trigger if the device has at least one
|
||||
button. While the server does not prevent a button class with zero
|
||||
buttons, it is very unlikely.
|
||||
|
||||
CVE-2024-0229, ZDI-CAN-22678
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
(cherry picked from commit ece23be888a93b741aa1209d1dbf64636109d6a5)
|
||||
---
|
||||
dix/enterleave.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dix/enterleave.c b/dix/enterleave.c
|
||||
index ded8679d7..17964b00a 100644
|
||||
--- a/dix/enterleave.c
|
||||
+++ b/dix/enterleave.c
|
||||
@@ -675,7 +675,8 @@ static void
|
||||
DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
|
||||
{
|
||||
int evcount = 1;
|
||||
- deviceStateNotify *ev, *sev;
|
||||
+ deviceStateNotify sev[6 + (MAX_VALUATORS + 2)/3];
|
||||
+ deviceStateNotify *ev;
|
||||
deviceKeyStateNotify *kev;
|
||||
deviceButtonStateNotify *bev;
|
||||
|
||||
@@ -714,7 +715,7 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
|
||||
}
|
||||
}
|
||||
|
||||
- sev = ev = xallocarray(evcount, sizeof(xEvent));
|
||||
+ ev = sev;
|
||||
FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
|
||||
|
||||
if (b != NULL) {
|
||||
@@ -770,7 +771,6 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
|
||||
|
||||
DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount,
|
||||
DeviceStateNotifyMask, NullGrab);
|
||||
- free(sev);
|
||||
}
|
||||
|
||||
void
|
||||
--
|
||||
2.43.0
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
From 45a0af83129eb7dc244c5118360afc1972a686c7 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 5 Jul 2022 09:50:41 +1000
|
||||
Subject: [PATCH xserver 2/3] xkb: swap XkbSetDeviceInfo and
|
||||
XkbSetDeviceInfoCheck
|
||||
|
||||
XKB often uses a FooCheck and Foo function pair, the former is supposed
|
||||
to check all values in the request and error out on BadLength,
|
||||
BadValue, etc. The latter is then called once we're confident the values
|
||||
are good (they may still fail on an individual device, but that's a
|
||||
different topic).
|
||||
|
||||
In the case of XkbSetDeviceInfo, those functions were incorrectly
|
||||
named, with XkbSetDeviceInfo ending up as the checker function and
|
||||
XkbSetDeviceInfoCheck as the setter function. As a result, the setter
|
||||
function was called before the checker function, accessing request
|
||||
data and modifying device state before we ensured that the data is
|
||||
valid.
|
||||
|
||||
In particular, the setter function relied on values being already
|
||||
byte-swapped. This in turn could lead to potential OOB memory access.
|
||||
|
||||
Fix this by correctly naming the functions and moving the length checks
|
||||
over to the checker function. These were added in 87c64fc5b0 to the
|
||||
wrong function, probably due to the incorrect naming.
|
||||
|
||||
Fixes ZDI-CAN 16070, CVE-2022-2320.
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Introduced in c06e27b2f6fd9f7b9f827623a48876a225264132
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
(cherry picked from commit dd8caf39e9e15d8f302e54045dd08d8ebf1025dc)
|
||||
---
|
||||
xkb/xkb.c | 46 +++++++++++++++++++++++++---------------------
|
||||
1 file changed, 25 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/xkb/xkb.c b/xkb/xkb.c
|
||||
index 684394d77..36464a770 100644
|
||||
--- a/xkb/xkb.c
|
||||
+++ b/xkb/xkb.c
|
||||
@@ -6554,7 +6554,8 @@ ProcXkbGetDeviceInfo(ClientPtr client)
|
||||
static char *
|
||||
CheckSetDeviceIndicators(char *wire,
|
||||
DeviceIntPtr dev,
|
||||
- int num, int *status_rtrn, ClientPtr client)
|
||||
+ int num, int *status_rtrn, ClientPtr client,
|
||||
+ xkbSetDeviceInfoReq * stuff)
|
||||
{
|
||||
xkbDeviceLedsWireDesc *ledWire;
|
||||
int i;
|
||||
@@ -6562,6 +6563,11 @@ CheckSetDeviceIndicators(char *wire,
|
||||
|
||||
ledWire = (xkbDeviceLedsWireDesc *) wire;
|
||||
for (i = 0; i < num; i++) {
|
||||
+ if (!_XkbCheckRequestBounds(client, stuff, ledWire, ledWire + 1)) {
|
||||
+ *status_rtrn = BadLength;
|
||||
+ return (char *) ledWire;
|
||||
+ }
|
||||
+
|
||||
if (client->swapped) {
|
||||
swaps(&ledWire->ledClass);
|
||||
swaps(&ledWire->ledID);
|
||||
@@ -6589,6 +6595,11 @@ CheckSetDeviceIndicators(char *wire,
|
||||
atomWire = (CARD32 *) &ledWire[1];
|
||||
if (nNames > 0) {
|
||||
for (n = 0; n < nNames; n++) {
|
||||
+ if (!_XkbCheckRequestBounds(client, stuff, atomWire, atomWire + 1)) {
|
||||
+ *status_rtrn = BadLength;
|
||||
+ return (char *) atomWire;
|
||||
+ }
|
||||
+
|
||||
if (client->swapped) {
|
||||
swapl(atomWire);
|
||||
}
|
||||
@@ -6600,6 +6611,10 @@ CheckSetDeviceIndicators(char *wire,
|
||||
mapWire = (xkbIndicatorMapWireDesc *) atomWire;
|
||||
if (nMaps > 0) {
|
||||
for (n = 0; n < nMaps; n++) {
|
||||
+ if (!_XkbCheckRequestBounds(client, stuff, mapWire, mapWire + 1)) {
|
||||
+ *status_rtrn = BadLength;
|
||||
+ return (char *) mapWire;
|
||||
+ }
|
||||
if (client->swapped) {
|
||||
swaps(&mapWire->virtualMods);
|
||||
swapl(&mapWire->ctrls);
|
||||
@@ -6651,11 +6666,6 @@ SetDeviceIndicators(char *wire,
|
||||
xkbIndicatorMapWireDesc *mapWire;
|
||||
XkbSrvLedInfoPtr sli;
|
||||
|
||||
- if (!_XkbCheckRequestBounds(client, stuff, ledWire, ledWire + 1)) {
|
||||
- *status_rtrn = BadLength;
|
||||
- return (char *) ledWire;
|
||||
- }
|
||||
-
|
||||
namec = mapc = statec = 0;
|
||||
sli = XkbFindSrvLedInfo(dev, ledWire->ledClass, ledWire->ledID,
|
||||
XkbXI_IndicatorMapsMask);
|
||||
@@ -6674,10 +6684,6 @@ SetDeviceIndicators(char *wire,
|
||||
memset((char *) sli->names, 0, XkbNumIndicators * sizeof(Atom));
|
||||
for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) {
|
||||
if (ledWire->namesPresent & bit) {
|
||||
- if (!_XkbCheckRequestBounds(client, stuff, atomWire, atomWire + 1)) {
|
||||
- *status_rtrn = BadLength;
|
||||
- return (char *) atomWire;
|
||||
- }
|
||||
sli->names[n] = (Atom) *atomWire;
|
||||
if (sli->names[n] == None)
|
||||
ledWire->namesPresent &= ~bit;
|
||||
@@ -6695,10 +6701,6 @@ SetDeviceIndicators(char *wire,
|
||||
if (ledWire->mapsPresent) {
|
||||
for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) {
|
||||
if (ledWire->mapsPresent & bit) {
|
||||
- if (!_XkbCheckRequestBounds(client, stuff, mapWire, mapWire + 1)) {
|
||||
- *status_rtrn = BadLength;
|
||||
- return (char *) mapWire;
|
||||
- }
|
||||
sli->maps[n].flags = mapWire->flags;
|
||||
sli->maps[n].which_groups = mapWire->whichGroups;
|
||||
sli->maps[n].groups = mapWire->groups;
|
||||
@@ -6734,13 +6736,17 @@ SetDeviceIndicators(char *wire,
|
||||
}
|
||||
|
||||
static int
|
||||
-_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev,
|
||||
+_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev,
|
||||
xkbSetDeviceInfoReq * stuff)
|
||||
{
|
||||
char *wire;
|
||||
|
||||
wire = (char *) &stuff[1];
|
||||
if (stuff->change & XkbXI_ButtonActionsMask) {
|
||||
+ int sz = stuff->nBtns * SIZEOF(xkbActionWireDesc);
|
||||
+ if (!_XkbCheckRequestBounds(client, stuff, wire, (char *) wire + sz))
|
||||
+ return BadLength;
|
||||
+
|
||||
if (!dev->button) {
|
||||
client->errorValue = _XkbErrCode2(XkbErr_BadClass, ButtonClass);
|
||||
return XkbKeyboardErrorCode;
|
||||
@@ -6751,13 +6757,13 @@ _XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev,
|
||||
dev->button->numButtons);
|
||||
return BadMatch;
|
||||
}
|
||||
- wire += (stuff->nBtns * SIZEOF(xkbActionWireDesc));
|
||||
+ wire += sz;
|
||||
}
|
||||
if (stuff->change & XkbXI_IndicatorsMask) {
|
||||
int status = Success;
|
||||
|
||||
wire = CheckSetDeviceIndicators(wire, dev, stuff->nDeviceLedFBs,
|
||||
- &status, client);
|
||||
+ &status, client, stuff);
|
||||
if (status != Success)
|
||||
return status;
|
||||
}
|
||||
@@ -6768,8 +6774,8 @@ _XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev,
|
||||
}
|
||||
|
||||
static int
|
||||
-_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev,
|
||||
- xkbSetDeviceInfoReq * stuff)
|
||||
+_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev,
|
||||
+ xkbSetDeviceInfoReq * stuff)
|
||||
{
|
||||
char *wire;
|
||||
xkbExtensionDeviceNotify ed;
|
||||
@@ -6793,8 +6799,6 @@ _XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev,
|
||||
if (stuff->firstBtn + stuff->nBtns > nBtns)
|
||||
return BadValue;
|
||||
sz = stuff->nBtns * SIZEOF(xkbActionWireDesc);
|
||||
- if (!_XkbCheckRequestBounds(client, stuff, wire, (char *) wire + sz))
|
||||
- return BadLength;
|
||||
memcpy((char *) &acts[stuff->firstBtn], (char *) wire, sz);
|
||||
wire += sz;
|
||||
ed.reason |= XkbXI_ButtonActionsMask;
|
||||
--
|
||||
2.36.1
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
From f9c435822c852659e3926502829f1b13ce6efc37 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 29 Nov 2022 13:26:57 +1000
|
||||
Subject: [PATCH xserver 3/7] Xi: avoid integer truncation in length check of
|
||||
ProcXIChangeProperty
|
||||
|
||||
This fixes an OOB read and the resulting information disclosure.
|
||||
|
||||
Length calculation for the request was clipped to a 32-bit integer. With
|
||||
the correct stuff->num_items value the expected request size was
|
||||
truncated, passing the REQUEST_FIXED_SIZE check.
|
||||
|
||||
The server then proceeded with reading at least stuff->num_items bytes
|
||||
(depending on stuff->format) from the request and stuffing whatever it
|
||||
finds into the property. In the process it would also allocate at least
|
||||
stuff->num_items bytes, i.e. 4GB.
|
||||
|
||||
The same bug exists in ProcChangeProperty and ProcXChangeDeviceProperty,
|
||||
so let's fix that too.
|
||||
|
||||
CVE-2022-46344, ZDI-CAN 19405
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
---
|
||||
Xi/xiproperty.c | 4 ++--
|
||||
dix/property.c | 3 ++-
|
||||
2 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
|
||||
index 68c362c628..066ba21fba 100644
|
||||
--- a/Xi/xiproperty.c
|
||||
+++ b/Xi/xiproperty.c
|
||||
@@ -890,7 +890,7 @@ ProcXChangeDeviceProperty(ClientPtr client)
|
||||
REQUEST(xChangeDevicePropertyReq);
|
||||
DeviceIntPtr dev;
|
||||
unsigned long len;
|
||||
- int totalSize;
|
||||
+ uint64_t totalSize;
|
||||
int rc;
|
||||
|
||||
REQUEST_AT_LEAST_SIZE(xChangeDevicePropertyReq);
|
||||
@@ -1130,7 +1130,7 @@ ProcXIChangeProperty(ClientPtr client)
|
||||
{
|
||||
int rc;
|
||||
DeviceIntPtr dev;
|
||||
- int totalSize;
|
||||
+ uint64_t totalSize;
|
||||
unsigned long len;
|
||||
|
||||
REQUEST(xXIChangePropertyReq);
|
||||
diff --git a/dix/property.c b/dix/property.c
|
||||
index 94ef5a0ec0..acce94b2c6 100644
|
||||
--- a/dix/property.c
|
||||
+++ b/dix/property.c
|
||||
@@ -205,7 +205,8 @@ ProcChangeProperty(ClientPtr client)
|
||||
WindowPtr pWin;
|
||||
char format, mode;
|
||||
unsigned long len;
|
||||
- int sizeInBytes, totalSize, err;
|
||||
+ int sizeInBytes, err;
|
||||
+ uint64_t totalSize;
|
||||
|
||||
REQUEST(xChangePropertyReq);
|
||||
|
||||
--
|
||||
2.38.1
|
|
@ -0,0 +1,219 @@
|
|||
From ee5377d94ea587f584adbc9ab8372b3842cfa149 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Mon, 18 Dec 2023 12:26:20 +1000
|
||||
Subject: [PATCH xserver 3/9] dix: fix DeviceStateNotify event calculation
|
||||
|
||||
The previous code only made sense if one considers buttons and keys to
|
||||
be mutually exclusive on a device. That is not necessarily true, causing
|
||||
a number of issues.
|
||||
|
||||
This function allocates and fills in the number of xEvents we need to
|
||||
send the device state down the wire. This is split across multiple
|
||||
32-byte devices including one deviceStateNotify event and optional
|
||||
deviceKeyStateNotify, deviceButtonStateNotify and (possibly multiple)
|
||||
deviceValuator events.
|
||||
|
||||
The previous behavior would instead compose a sequence
|
||||
of [state, buttonstate, state, keystate, valuator...]. This is not
|
||||
protocol correct, and on top of that made the code extremely convoluted.
|
||||
|
||||
Fix this by streamlining: add both button and key into the deviceStateNotify
|
||||
and then append the key state and button state, followed by the
|
||||
valuators. Finally, the deviceValuator events contain up to 6 valuators
|
||||
per event but we only ever sent through 3 at a time. Let's double that
|
||||
troughput.
|
||||
|
||||
CVE-2024-0229, ZDI-CAN-22678
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
(cherry picked from commit 219c54b8a3337456ce5270ded6a67bcde53553d5)
|
||||
---
|
||||
dix/enterleave.c | 121 ++++++++++++++++++++---------------------------
|
||||
1 file changed, 52 insertions(+), 69 deletions(-)
|
||||
|
||||
diff --git a/dix/enterleave.c b/dix/enterleave.c
|
||||
index 17964b00a..7b7ba1098 100644
|
||||
--- a/dix/enterleave.c
|
||||
+++ b/dix/enterleave.c
|
||||
@@ -615,9 +615,15 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
|
||||
|
||||
ev->type = DeviceValuator;
|
||||
ev->deviceid = dev->id;
|
||||
- ev->num_valuators = nval < 3 ? nval : 3;
|
||||
+ ev->num_valuators = nval < 6 ? nval : 6;
|
||||
ev->first_valuator = first;
|
||||
switch (ev->num_valuators) {
|
||||
+ case 6:
|
||||
+ ev->valuator2 = v->axisVal[first + 5];
|
||||
+ case 5:
|
||||
+ ev->valuator2 = v->axisVal[first + 4];
|
||||
+ case 4:
|
||||
+ ev->valuator2 = v->axisVal[first + 3];
|
||||
case 3:
|
||||
ev->valuator2 = v->axisVal[first + 2];
|
||||
case 2:
|
||||
@@ -626,7 +632,6 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
|
||||
ev->valuator0 = v->axisVal[first];
|
||||
break;
|
||||
}
|
||||
- first += ev->num_valuators;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -646,7 +651,7 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
|
||||
ev->num_buttons = b->numButtons;
|
||||
memcpy((char *) ev->buttons, (char *) b->down, 4);
|
||||
}
|
||||
- else if (k) {
|
||||
+ if (k) {
|
||||
ev->classes_reported |= (1 << KeyClass);
|
||||
ev->num_keys = k->xkbInfo->desc->max_key_code -
|
||||
k->xkbInfo->desc->min_key_code;
|
||||
@@ -670,15 +675,26 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
|
||||
}
|
||||
}
|
||||
|
||||
-
|
||||
+/**
|
||||
+ * The device state notify event is split across multiple 32-byte events.
|
||||
+ * The first one contains the first 32 button state bits, the first 32
|
||||
+ * key state bits, and the first 3 valuator values.
|
||||
+ *
|
||||
+ * If a device has more than that, the server sends out:
|
||||
+ * - one deviceButtonStateNotify for buttons 32 and above
|
||||
+ * - one deviceKeyStateNotify for keys 32 and above
|
||||
+ * - one deviceValuator event per 6 valuators above valuator 4
|
||||
+ *
|
||||
+ * All events but the last one have the deviceid binary ORed with MORE_EVENTS,
|
||||
+ */
|
||||
static void
|
||||
DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
|
||||
{
|
||||
+ /* deviceStateNotify, deviceKeyStateNotify, deviceButtonStateNotify
|
||||
+ * and one deviceValuator for each 6 valuators */
|
||||
+ deviceStateNotify sev[3 + (MAX_VALUATORS + 6)/6];
|
||||
int evcount = 1;
|
||||
- deviceStateNotify sev[6 + (MAX_VALUATORS + 2)/3];
|
||||
- deviceStateNotify *ev;
|
||||
- deviceKeyStateNotify *kev;
|
||||
- deviceButtonStateNotify *bev;
|
||||
+ deviceStateNotify *ev = sev;
|
||||
|
||||
KeyClassPtr k;
|
||||
ButtonClassPtr b;
|
||||
@@ -691,82 +707,49 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
|
||||
|
||||
if ((b = dev->button) != NULL) {
|
||||
nbuttons = b->numButtons;
|
||||
- if (nbuttons > 32)
|
||||
+ if (nbuttons > 32) /* first 32 are encoded in deviceStateNotify */
|
||||
evcount++;
|
||||
}
|
||||
if ((k = dev->key) != NULL) {
|
||||
nkeys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code;
|
||||
- if (nkeys > 32)
|
||||
+ if (nkeys > 32) /* first 32 are encoded in deviceStateNotify */
|
||||
evcount++;
|
||||
- if (nbuttons > 0) {
|
||||
- evcount++;
|
||||
- }
|
||||
}
|
||||
if ((v = dev->valuator) != NULL) {
|
||||
nval = v->numAxes;
|
||||
-
|
||||
- if (nval > 3)
|
||||
- evcount++;
|
||||
- if (nval > 6) {
|
||||
- if (!(k && b))
|
||||
- evcount++;
|
||||
- if (nval > 9)
|
||||
- evcount += ((nval - 7) / 3);
|
||||
- }
|
||||
+ /* first three are encoded in deviceStateNotify, then
|
||||
+ * it's 6 per deviceValuator event */
|
||||
+ evcount += ((nval - 3) + 6)/6;
|
||||
}
|
||||
|
||||
- ev = sev;
|
||||
- FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
|
||||
-
|
||||
- if (b != NULL) {
|
||||
- FixDeviceStateNotify(dev, ev++, NULL, b, v, first);
|
||||
- first += 3;
|
||||
- nval -= 3;
|
||||
- if (nbuttons > 32) {
|
||||
- (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
- bev = (deviceButtonStateNotify *) ev++;
|
||||
- bev->type = DeviceButtonStateNotify;
|
||||
- bev->deviceid = dev->id;
|
||||
- memcpy((char *) &bev->buttons[4], (char *) &b->down[4],
|
||||
- DOWN_LENGTH - 4);
|
||||
- }
|
||||
- if (nval > 0) {
|
||||
- (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
|
||||
- first += 3;
|
||||
- nval -= 3;
|
||||
- }
|
||||
+ BUG_RETURN(evcount <= ARRAY_SIZE(sev));
|
||||
+
|
||||
+ FixDeviceStateNotify(dev, ev, k, b, v, first);
|
||||
+
|
||||
+ if (b != NULL && nbuttons > 32) {
|
||||
+ deviceButtonStateNotify *bev = (deviceButtonStateNotify *) ++ev;
|
||||
+ (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
+ bev->type = DeviceButtonStateNotify;
|
||||
+ bev->deviceid = dev->id;
|
||||
+ memcpy((char *) &bev->buttons[4], (char *) &b->down[4],
|
||||
+ DOWN_LENGTH - 4);
|
||||
}
|
||||
|
||||
- if (k != NULL) {
|
||||
- FixDeviceStateNotify(dev, ev++, k, NULL, v, first);
|
||||
- first += 3;
|
||||
- nval -= 3;
|
||||
- if (nkeys > 32) {
|
||||
- (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
- kev = (deviceKeyStateNotify *) ev++;
|
||||
- kev->type = DeviceKeyStateNotify;
|
||||
- kev->deviceid = dev->id;
|
||||
- memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
|
||||
- }
|
||||
- if (nval > 0) {
|
||||
- (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
|
||||
- first += 3;
|
||||
- nval -= 3;
|
||||
- }
|
||||
+ if (k != NULL && nkeys > 32) {
|
||||
+ deviceKeyStateNotify *kev = (deviceKeyStateNotify *) ++ev;
|
||||
+ (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
+ kev->type = DeviceKeyStateNotify;
|
||||
+ kev->deviceid = dev->id;
|
||||
+ memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
|
||||
}
|
||||
|
||||
+ first = 3;
|
||||
+ nval -= 3;
|
||||
while (nval > 0) {
|
||||
- FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first);
|
||||
- first += 3;
|
||||
- nval -= 3;
|
||||
- if (nval > 0) {
|
||||
- (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
|
||||
- first += 3;
|
||||
- nval -= 3;
|
||||
- }
|
||||
+ ev->deviceid |= MORE_EVENTS;
|
||||
+ FixDeviceValuator(dev, (deviceValuator *) ++ev, v, first);
|
||||
+ first += 6;
|
||||
+ nval -= 6;
|
||||
}
|
||||
|
||||
DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount,
|
||||
--
|
||||
2.43.0
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
From bd134231e282d9eb126b6fdaa40bb383180fa72b Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 5 Jul 2022 11:11:06 +1000
|
||||
Subject: [PATCH xserver 3/3] xkb: add request length validation for
|
||||
XkbSetGeometry
|
||||
|
||||
No validation of the various fields on that report were done, so a
|
||||
malicious client could send a short request that claims it had N
|
||||
sections, or rows, or keys, and the server would process the request for
|
||||
N sections, running out of bounds of the actual request data.
|
||||
|
||||
Fix this by adding size checks to ensure our data is valid.
|
||||
|
||||
ZDI-CAN 16062, CVE-2022-2319.
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
(cherry picked from commit 6907b6ea2b4ce949cb07271f5b678d5966d9df42)
|
||||
---
|
||||
xkb/xkb.c | 43 ++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 38 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/xkb/xkb.c b/xkb/xkb.c
|
||||
index 36464a770..27d19793e 100644
|
||||
--- a/xkb/xkb.c
|
||||
+++ b/xkb/xkb.c
|
||||
@@ -5160,7 +5160,7 @@ _GetCountedString(char **wire_inout, ClientPtr client, char **str)
|
||||
}
|
||||
|
||||
static Status
|
||||
-_CheckSetDoodad(char **wire_inout,
|
||||
+_CheckSetDoodad(char **wire_inout, xkbSetGeometryReq *req,
|
||||
XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client)
|
||||
{
|
||||
char *wire;
|
||||
@@ -5171,6 +5171,9 @@ _CheckSetDoodad(char **wire_inout,
|
||||
Status status;
|
||||
|
||||
dWire = (xkbDoodadWireDesc *) (*wire_inout);
|
||||
+ if (!_XkbCheckRequestBounds(client, req, dWire, dWire + 1))
|
||||
+ return BadLength;
|
||||
+
|
||||
any = dWire->any;
|
||||
wire = (char *) &dWire[1];
|
||||
if (client->swapped) {
|
||||
@@ -5273,7 +5276,7 @@ _CheckSetDoodad(char **wire_inout,
|
||||
}
|
||||
|
||||
static Status
|
||||
-_CheckSetOverlay(char **wire_inout,
|
||||
+_CheckSetOverlay(char **wire_inout, xkbSetGeometryReq *req,
|
||||
XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client)
|
||||
{
|
||||
register int r;
|
||||
@@ -5284,6 +5287,9 @@ _CheckSetOverlay(char **wire_inout,
|
||||
|
||||
wire = *wire_inout;
|
||||
olWire = (xkbOverlayWireDesc *) wire;
|
||||
+ if (!_XkbCheckRequestBounds(client, req, olWire, olWire + 1))
|
||||
+ return BadLength;
|
||||
+
|
||||
if (client->swapped) {
|
||||
swapl(&olWire->name);
|
||||
}
|
||||
@@ -5295,6 +5301,9 @@ _CheckSetOverlay(char **wire_inout,
|
||||
xkbOverlayKeyWireDesc *kWire;
|
||||
XkbOverlayRowPtr row;
|
||||
|
||||
+ if (!_XkbCheckRequestBounds(client, req, rWire, rWire + 1))
|
||||
+ return BadLength;
|
||||
+
|
||||
if (rWire->rowUnder > section->num_rows) {
|
||||
client->errorValue = _XkbErrCode4(0x20, r, section->num_rows,
|
||||
rWire->rowUnder);
|
||||
@@ -5303,6 +5312,9 @@ _CheckSetOverlay(char **wire_inout,
|
||||
row = XkbAddGeomOverlayRow(ol, rWire->rowUnder, rWire->nKeys);
|
||||
kWire = (xkbOverlayKeyWireDesc *) &rWire[1];
|
||||
for (k = 0; k < rWire->nKeys; k++, kWire++) {
|
||||
+ if (!_XkbCheckRequestBounds(client, req, kWire, kWire + 1))
|
||||
+ return BadLength;
|
||||
+
|
||||
if (XkbAddGeomOverlayKey(ol, row,
|
||||
(char *) kWire->over,
|
||||
(char *) kWire->under) == NULL) {
|
||||
@@ -5336,6 +5348,9 @@ _CheckSetSections(XkbGeometryPtr geom,
|
||||
register int r;
|
||||
xkbRowWireDesc *rWire;
|
||||
|
||||
+ if (!_XkbCheckRequestBounds(client, req, sWire, sWire + 1))
|
||||
+ return BadLength;
|
||||
+
|
||||
if (client->swapped) {
|
||||
swapl(&sWire->name);
|
||||
swaps(&sWire->top);
|
||||
@@ -5361,6 +5376,9 @@ _CheckSetSections(XkbGeometryPtr geom,
|
||||
XkbRowPtr row;
|
||||
xkbKeyWireDesc *kWire;
|
||||
|
||||
+ if (!_XkbCheckRequestBounds(client, req, rWire, rWire + 1))
|
||||
+ return BadLength;
|
||||
+
|
||||
if (client->swapped) {
|
||||
swaps(&rWire->top);
|
||||
swaps(&rWire->left);
|
||||
@@ -5375,6 +5393,9 @@ _CheckSetSections(XkbGeometryPtr geom,
|
||||
for (k = 0; k < rWire->nKeys; k++, kWire++) {
|
||||
XkbKeyPtr key;
|
||||
|
||||
+ if (!_XkbCheckRequestBounds(client, req, kWire, kWire + 1))
|
||||
+ return BadLength;
|
||||
+
|
||||
key = XkbAddGeomKey(row);
|
||||
if (!key)
|
||||
return BadAlloc;
|
||||
@@ -5400,7 +5421,7 @@ _CheckSetSections(XkbGeometryPtr geom,
|
||||
register int d;
|
||||
|
||||
for (d = 0; d < sWire->nDoodads; d++) {
|
||||
- status = _CheckSetDoodad(&wire, geom, section, client);
|
||||
+ status = _CheckSetDoodad(&wire, req, geom, section, client);
|
||||
if (status != Success)
|
||||
return status;
|
||||
}
|
||||
@@ -5409,7 +5430,7 @@ _CheckSetSections(XkbGeometryPtr geom,
|
||||
register int o;
|
||||
|
||||
for (o = 0; o < sWire->nOverlays; o++) {
|
||||
- status = _CheckSetOverlay(&wire, geom, section, client);
|
||||
+ status = _CheckSetOverlay(&wire, req, geom, section, client);
|
||||
if (status != Success)
|
||||
return status;
|
||||
}
|
||||
@@ -5443,6 +5464,9 @@ _CheckSetShapes(XkbGeometryPtr geom,
|
||||
xkbOutlineWireDesc *olWire;
|
||||
XkbOutlinePtr ol;
|
||||
|
||||
+ if (!_XkbCheckRequestBounds(client, req, shapeWire, shapeWire + 1))
|
||||
+ return BadLength;
|
||||
+
|
||||
shape =
|
||||
XkbAddGeomShape(geom, shapeWire->name, shapeWire->nOutlines);
|
||||
if (!shape)
|
||||
@@ -5453,12 +5477,18 @@ _CheckSetShapes(XkbGeometryPtr geom,
|
||||
XkbPointPtr pt;
|
||||
xkbPointWireDesc *ptWire;
|
||||
|
||||
+ if (!_XkbCheckRequestBounds(client, req, olWire, olWire + 1))
|
||||
+ return BadLength;
|
||||
+
|
||||
ol = XkbAddGeomOutline(shape, olWire->nPoints);
|
||||
if (!ol)
|
||||
return BadAlloc;
|
||||
ol->corner_radius = olWire->cornerRadius;
|
||||
ptWire = (xkbPointWireDesc *) &olWire[1];
|
||||
for (p = 0, pt = ol->points; p < olWire->nPoints; p++, pt++, ptWire++) {
|
||||
+ if (!_XkbCheckRequestBounds(client, req, ptWire, ptWire + 1))
|
||||
+ return BadLength;
|
||||
+
|
||||
pt->x = ptWire->x;
|
||||
pt->y = ptWire->y;
|
||||
if (client->swapped) {
|
||||
@@ -5564,12 +5594,15 @@ _CheckSetGeom(XkbGeometryPtr geom, xkbSetGeometryReq * req, ClientPtr client)
|
||||
return status;
|
||||
|
||||
for (i = 0; i < req->nDoodads; i++) {
|
||||
- status = _CheckSetDoodad(&wire, geom, NULL, client);
|
||||
+ status = _CheckSetDoodad(&wire, req, geom, NULL, client);
|
||||
if (status != Success)
|
||||
return status;
|
||||
}
|
||||
|
||||
for (i = 0; i < req->nKeyAliases; i++) {
|
||||
+ if (!_XkbCheckRequestBounds(client, req, wire, wire + XkbKeyNameLength))
|
||||
+ return BadLength;
|
||||
+
|
||||
if (XkbAddGeomKeyAlias(geom, &wire[XkbKeyNameLength], wire) == NULL)
|
||||
return BadAlloc;
|
||||
wire += 2 * XkbKeyNameLength;
|
||||
--
|
||||
2.36.1
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
From 0dab0b527ac5c4fe0272ea679522bd87238a733b Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 29 Nov 2022 13:55:32 +1000
|
||||
Subject: [PATCH xserver 4/7] Xi: disallow passive grabs with a detail > 255
|
||||
|
||||
The XKB protocol effectively prevents us from ever using keycodes above
|
||||
255. For buttons it's theoretically possible but realistically too niche
|
||||
to worry about. For all other passive grabs, the detail must be zero
|
||||
anyway.
|
||||
|
||||
This fixes an OOB write:
|
||||
|
||||
ProcXIPassiveUngrabDevice() calls DeletePassiveGrabFromList with a
|
||||
temporary grab struct which contains tempGrab->detail.exact = stuff->detail.
|
||||
For matching existing grabs, DeleteDetailFromMask is called with the
|
||||
stuff->detail value. This function creates a new mask with the one bit
|
||||
representing stuff->detail cleared.
|
||||
|
||||
However, the array size for the new mask is 8 * sizeof(CARD32) bits,
|
||||
thus any detail above 255 results in an OOB array write.
|
||||
|
||||
CVE-2022-46341, ZDI-CAN 19381
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
---
|
||||
Xi/xipassivegrab.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
|
||||
index 65d5870f6f..89a591098a 100644
|
||||
--- a/Xi/xipassivegrab.c
|
||||
+++ b/Xi/xipassivegrab.c
|
||||
@@ -133,6 +133,12 @@ ProcXIPassiveGrabDevice(ClientPtr client)
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
+ /* XI2 allows 32-bit keycodes but thanks to XKB we can never
|
||||
+ * implement this. Just return an error for all keycodes that
|
||||
+ * cannot work anyway, same for buttons > 255. */
|
||||
+ if (stuff->detail > 255)
|
||||
+ return XIAlreadyGrabbed;
|
||||
+
|
||||
if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1],
|
||||
stuff->mask_len * 4) != Success)
|
||||
return BadValue;
|
||||
@@ -313,6 +319,12 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
+ /* We don't allow passive grabs for details > 255 anyway */
|
||||
+ if (stuff->detail > 255) {
|
||||
+ client->errorValue = stuff->detail;
|
||||
+ return BadValue;
|
||||
+ }
|
||||
+
|
||||
rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
|
||||
if (rc != Success)
|
||||
return rc;
|
||||
--
|
||||
2.38.1
|
|
@ -0,0 +1,39 @@
|
|||
From 1c22e4a35e71d98a082ad2f8f7bc778a8859e18d Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Thu, 21 Dec 2023 13:48:10 +1000
|
||||
Subject: [PATCH xserver 4/9] Xi: when creating a new ButtonClass, set the
|
||||
number of buttons
|
||||
|
||||
There's a racy sequence where a master device may copy the button class
|
||||
from the slave, without ever initializing numButtons. This leads to a
|
||||
device with zero buttons but a button class which is invalid.
|
||||
|
||||
Let's copy the numButtons value from the source - by definition if we
|
||||
don't have a button class yet we do not have any other slave devices
|
||||
with more than this number of buttons anyway.
|
||||
|
||||
CVE-2024-0229, ZDI-CAN-22678
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
(cherry picked from commit df3c65706eb169d5938df0052059f3e0d5981b74)
|
||||
---
|
||||
Xi/exevents.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/Xi/exevents.c b/Xi/exevents.c
|
||||
index 54ea11a93..e16171468 100644
|
||||
--- a/Xi/exevents.c
|
||||
+++ b/Xi/exevents.c
|
||||
@@ -605,6 +605,7 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
|
||||
to->button = calloc(1, sizeof(ButtonClassRec));
|
||||
if (!to->button)
|
||||
FatalError("[Xi] no memory for class shift.\n");
|
||||
+ to->button->numButtons = from->button->numButtons;
|
||||
}
|
||||
else
|
||||
classes->button = NULL;
|
||||
--
|
||||
2.43.0
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
+ image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT;
|
||||
+ image_attribs[attrib++] = mod_lo;
|
||||
+ }
|
||||
+ image_attribs[attrib++] = EGL_NONE;
|
||||
+
|
||||
+ xwl_glamor_egl_make_current(xwl_screen);
|
||||
+
|
||||
+ /* eglCreateImageKHR will close fds */
|
||||
+ xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
|
||||
+ EGL_NO_CONTEXT,
|
||||
+ EGL_LINUX_DMA_BUF_EXT,
|
||||
+ NULL, image_attribs);
|
||||
+ if (xwl_pixmap->image == EGL_NO_IMAGE_KHR) {
|
||||
+ ErrorF("eglCreateImageKHR failed!\n");
|
||||
+ if (xwl_pixmap->buffer)
|
||||
+ wl_buffer_destroy(xwl_pixmap->buffer);
|
||||
+ free(xwl_pixmap);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ glGenTextures(1, &texture);
|
||||
+ glBindTexture(GL_TEXTURE_2D, texture);
|
||||
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, xwl_pixmap->image);
|
||||
+ glBindTexture(GL_TEXTURE_2D, 0);
|
||||
+
|
||||
+ pixmap = glamor_create_pixmap(screen, width, height, depth,
|
||||
+ GLAMOR_CREATE_PIXMAP_NO_TEXTURE);
|
||||
+ glamor_set_pixmap_texture(pixmap, texture);
|
||||
+ glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
|
||||
+ wl_buffer_add_listener(xwl_pixmap->buffer,
|
||||
+ &xwl_eglstream_buffer_release_listener,
|
||||
+ pixmap);
|
||||
+ xwl_pixmap_set_private(pixmap, xwl_pixmap);
|
||||
+
|
||||
+ return pixmap;
|
||||
+}
|
||||
+
|
||||
+static const dri3_screen_info_rec xwl_dri3_info = {
|
||||
+ .version = 2,
|
||||
+ .open = NULL,
|
||||
+ .pixmap_from_fds = xwl_dri3_pixmap_from_fds,
|
||||
+ .fds_from_pixmap = NULL,
|
||||
+ .open_client = xwl_dri3_open_client,
|
||||
+ .get_formats = xwl_glamor_get_formats,
|
||||
+ .get_modifiers = xwl_glamor_get_modifiers,
|
||||
+ .get_drawable_modifiers = glamor_get_drawable_modifiers,
|
||||
+};
|
||||
+
|
||||
static Bool
|
||||
xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
@@ -858,6 +1045,11 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
|
||||
|
||||
xwl_eglstream_init_shaders(xwl_screen);
|
||||
|
||||
+ if (epoxy_has_gl_extension("GL_OES_EGL_image") &&
|
||||
+ !dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) {
|
||||
+ ErrorF("DRI3 initialization failed. Performance will be affected.\n");
|
||||
+ }
|
||||
+
|
||||
return TRUE;
|
||||
error:
|
||||
xwl_eglstream_cleanup(xwl_screen);
|
||||
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
|
||||
index 1b1d517da..12d820e44 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-gbm.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-gbm.c
|
||||
@@ -969,7 +969,6 @@ xwl_glamor_init_gbm(struct xwl_screen *xwl_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 |
|
||||
+ xwl_screen->gbm_backend.backend_flags = XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH |
|
||||
XWL_EGL_BACKEND_NEEDS_N_BUFFERING;
|
||||
}
|
||||
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
|
||||
index 060471f01..9e44d5106 100644
|
||||
--- a/hw/xwayland/xwayland-glamor.c
|
||||
+++ b/hw/xwayland/xwayland-glamor.c
|
||||
@@ -362,16 +362,6 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-Bool
|
||||
-xwl_glamor_has_present_flip(struct xwl_screen *xwl_screen)
|
||||
-{
|
||||
- if (!xwl_screen->glamor || !xwl_screen->egl_backend)
|
||||
- return FALSE;
|
||||
-
|
||||
- return (xwl_screen->egl_backend->backend_flags &
|
||||
- XWL_EGL_BACKEND_HAS_PRESENT_FLIP);
|
||||
-}
|
||||
-
|
||||
Bool
|
||||
xwl_glamor_needs_buffer_flush(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
@@ -430,8 +420,6 @@ xwl_glamor_select_eglstream_backend(struct xwl_screen *xwl_screen)
|
||||
#ifdef XWL_HAS_EGLSTREAM
|
||||
if (xwl_screen->eglstream_backend.is_available &&
|
||||
xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->eglstream_backend)) {
|
||||
- ErrorF("glamor: Using nvidia's EGLStream interface, direct rendering impossible.\n");
|
||||
- ErrorF("glamor: Performance may be affected. Ask your vendor to support GBM!\n");
|
||||
xwl_screen->egl_backend = &xwl_screen->eglstream_backend;
|
||||
return TRUE;
|
||||
}
|
||||
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
|
||||
index a86b30b40..26ab78f04 100644
|
||||
--- a/hw/xwayland/xwayland-glamor.h
|
||||
+++ b/hw/xwayland/xwayland-glamor.h
|
||||
@@ -34,9 +34,8 @@
|
||||
|
||||
typedef enum _xwl_egl_backend_flags {
|
||||
XWL_EGL_BACKEND_NO_FLAG = 0,
|
||||
- XWL_EGL_BACKEND_HAS_PRESENT_FLIP = (1 << 0),
|
||||
- XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH = (1 << 1),
|
||||
- XWL_EGL_BACKEND_NEEDS_N_BUFFERING = (1 << 2),
|
||||
+ XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH = (1 << 0),
|
||||
+ XWL_EGL_BACKEND_NEEDS_N_BUFFERING = (1 << 1),
|
||||
} xwl_egl_backend_flags;
|
||||
|
||||
struct xwl_egl_backend {
|
||||
@@ -122,7 +121,6 @@ void xwl_glamor_post_damage(struct xwl_window *xwl_window,
|
||||
PixmapPtr pixmap, RegionPtr region);
|
||||
Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
|
||||
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,
|
||||
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
|
||||
index 666ea15e7..7ba7efc11 100644
|
||||
--- a/hw/xwayland/xwayland-present.c
|
||||
+++ b/hw/xwayland/xwayland-present.c
|
||||
@@ -404,6 +404,9 @@ xwl_present_check_flip2(RRCrtcPtr crtc,
|
||||
if (!xwl_window)
|
||||
return FALSE;
|
||||
|
||||
+ if (!xwl_glamor_check_flip(pixmap))
|
||||
+ return FALSE;
|
||||
+
|
||||
/* Can't flip if the window pixmap doesn't match the xwl_window parent
|
||||
* window's, e.g. because a client redirected this window or one of its
|
||||
* parents.
|
||||
@@ -540,7 +543,7 @@ xwl_present_init(ScreenPtr screen)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
|
||||
- if (!xwl_glamor_has_present_flip(xwl_screen))
|
||||
+ if (!xwl_screen->glamor || !xwl_screen->egl_backend)
|
||||
return FALSE;
|
||||
|
||||
if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
From 94f6fe99d87cf6ba0adadd95c595158c345b7d29 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 29 Nov 2022 14:53:07 +1000
|
||||
Subject: [PATCH xserver 5/7] Xext: free the screen saver resource when
|
||||
replacing it
|
||||
|
||||
This fixes a use-after-free bug:
|
||||
|
||||
When a client first calls ScreenSaverSetAttributes(), a struct
|
||||
ScreenSaverAttrRec is allocated and added to the client's
|
||||
resources.
|
||||
|
||||
When the same client calls ScreenSaverSetAttributes() again, a new
|
||||
struct ScreenSaverAttrRec is allocated, replacing the old struct. The
|
||||
old struct was freed but not removed from the clients resources.
|
||||
|
||||
Later, when the client is destroyed the resource system invokes
|
||||
ScreenSaverFreeAttr and attempts to clean up the already freed struct.
|
||||
|
||||
Fix this by letting the resource system free the old attrs instead.
|
||||
|
||||
CVE-2022-46343, ZDI-CAN 19404
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
---
|
||||
Xext/saver.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Xext/saver.c b/Xext/saver.c
|
||||
index f813ba08d1..fd6153c313 100644
|
||||
--- a/Xext/saver.c
|
||||
+++ b/Xext/saver.c
|
||||
@@ -1051,7 +1051,7 @@ ScreenSaverSetAttributes(ClientPtr client)
|
||||
pVlist++;
|
||||
}
|
||||
if (pPriv->attr)
|
||||
- FreeScreenAttr(pPriv->attr);
|
||||
+ FreeResource(pPriv->attr->resource, AttrType);
|
||||
pPriv->attr = pAttr;
|
||||
pAttr->resource = FakeClientID(client->index);
|
||||
if (!AddResource(pAttr->resource, AttrType, (void *) pAttr))
|
||||
--
|
||||
2.38.1
|
|
@ -0,0 +1,111 @@
|
|||
From 7efd09cdb13ae1a4100f68a11947afe581fa1ee8 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Thu, 4 Jan 2024 10:01:24 +1000
|
||||
Subject: [PATCH xserver 5/9] Xi: flush hierarchy events after adding/removing
|
||||
master devices
|
||||
|
||||
The `XISendDeviceHierarchyEvent()` function allocates space to store up
|
||||
to `MAXDEVICES` (256) `xXIHierarchyInfo` structures in `info`.
|
||||
|
||||
If a device with a given ID was removed and a new device with the same
|
||||
ID added both in the same operation, the single device ID will lead to
|
||||
two info structures being written to `info`.
|
||||
|
||||
Since this case can occur for every device ID at once, a total of two
|
||||
times `MAXDEVICES` info structures might be written to the allocation.
|
||||
|
||||
To avoid it, once one add/remove master is processed, send out the
|
||||
device hierarchy event for the current state and continue. That event
|
||||
thus only ever has exactly one of either added/removed in it (and
|
||||
optionally slave attached/detached).
|
||||
|
||||
CVE-2024-21885, ZDI-CAN-22744
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
(cherry picked from commit 4a5e9b1895627d40d26045bd0b7ef3dce503cbd1)
|
||||
---
|
||||
Xi/xichangehierarchy.c | 27 ++++++++++++++++++++++-----
|
||||
1 file changed, 22 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
|
||||
index d2d985848..72d00451e 100644
|
||||
--- a/Xi/xichangehierarchy.c
|
||||
+++ b/Xi/xichangehierarchy.c
|
||||
@@ -416,6 +416,11 @@ ProcXIChangeHierarchy(ClientPtr client)
|
||||
size_t len; /* length of data remaining in request */
|
||||
int rc = Success;
|
||||
int flags[MAXDEVICES] = { 0 };
|
||||
+ enum {
|
||||
+ NO_CHANGE,
|
||||
+ FLUSH,
|
||||
+ CHANGED,
|
||||
+ } changes = NO_CHANGE;
|
||||
|
||||
REQUEST(xXIChangeHierarchyReq);
|
||||
REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq);
|
||||
@@ -465,8 +470,9 @@ ProcXIChangeHierarchy(ClientPtr client)
|
||||
rc = add_master(client, c, flags);
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
- }
|
||||
+ changes = FLUSH;
|
||||
break;
|
||||
+ }
|
||||
case XIRemoveMaster:
|
||||
{
|
||||
xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any;
|
||||
@@ -475,8 +481,9 @@ ProcXIChangeHierarchy(ClientPtr client)
|
||||
rc = remove_master(client, r, flags);
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
- }
|
||||
+ changes = FLUSH;
|
||||
break;
|
||||
+ }
|
||||
case XIDetachSlave:
|
||||
{
|
||||
xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any;
|
||||
@@ -485,8 +492,9 @@ ProcXIChangeHierarchy(ClientPtr client)
|
||||
rc = detach_slave(client, c, flags);
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
- }
|
||||
+ changes = CHANGED;
|
||||
break;
|
||||
+ }
|
||||
case XIAttachSlave:
|
||||
{
|
||||
xXIAttachSlaveInfo *c = (xXIAttachSlaveInfo *) any;
|
||||
@@ -495,16 +503,25 @@ ProcXIChangeHierarchy(ClientPtr client)
|
||||
rc = attach_slave(client, c, flags);
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
+ changes = CHANGED;
|
||||
+ break;
|
||||
}
|
||||
+ default:
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (changes == FLUSH) {
|
||||
+ XISendDeviceHierarchyEvent(flags);
|
||||
+ memset(flags, 0, sizeof(flags));
|
||||
+ changes = NO_CHANGE;
|
||||
+ }
|
||||
+
|
||||
len -= any->length * 4;
|
||||
any = (xXIAnyHierarchyChangeInfo *) ((char *) any + any->length * 4);
|
||||
}
|
||||
|
||||
unwind:
|
||||
-
|
||||
- XISendDeviceHierarchyEvent(flags);
|
||||
+ if (changes != NO_CHANGE)
|
||||
+ XISendDeviceHierarchyEvent(flags);
|
||||
return rc;
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
From 43d1648dc71d01628a6a65a62364c1a3994a88a8 Mon Sep 17 00:00:00 2001
|
||||
From: Erik Kurzinger <ekurzinger@nvidia.com>
|
||||
Date: Tue, 27 Apr 2021 07:23:44 -0400
|
||||
Subject: [PATCH xserver 05/27] xwayland-eglstream: fix X11 rendering to
|
||||
flipping GL / VK window
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If a window is being used for direct rendering with OpenGL or Vulkan, and is
|
||||
using the flipping path for presentation, it's pixmap will be set to a dma-buf
|
||||
backed pixmap created by the client-side GL driver. However, this means that
|
||||
xwl_glamor_eglstream_post_damage won't work since it requires that the pixmap
|
||||
has an EGLSurface that it can render to, which dma-buf backed pixmaps do not.
|
||||
|
||||
In this case, though, xwl_glamor_eglstream_post_damage is not necessary since
|
||||
glamor will have rendered directly to the pixmap, so we can simply pass it
|
||||
directly to the compositor. There's no need for the intermediate copy we
|
||||
normally do in that function.
|
||||
|
||||
Therefore, this change adds an early-return case to post_damage for dma-buf
|
||||
backed pixmaps, and removes the corresponding asserts from that function and
|
||||
allow_commits.
|
||||
|
||||
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
|
||||
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
(cherry picked from commit 4f6fbd5009ae533cf0b3bbe382502254f9276a01)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 2d8380e1f..17295f3bd 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -576,7 +576,6 @@ 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 */
|
||||
@@ -615,7 +614,12 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
|
||||
};
|
||||
GLint saved_vao;
|
||||
|
||||
- assert(xwl_pixmap->type == XWL_PIXMAP_EGLSTREAM);
|
||||
+ if (xwl_pixmap->type != XWL_PIXMAP_EGLSTREAM)
|
||||
+ /* This can happen if a client does X11 rendering on a
|
||||
+ * flipping OpenGL or Vulkan window. In that case, we don't
|
||||
+ * need to do the copy below.
|
||||
+ */
|
||||
+ return;
|
||||
|
||||
/* Unbind the framebuffer BEFORE binding the EGLSurface, otherwise we
|
||||
* won't actually draw to it
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
From a42635ee3c01f71a49052d83a372933504c9db04 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Wed, 30 Nov 2022 11:20:40 +1000
|
||||
Subject: [PATCH xserver 6/7] Xext: free the XvRTVideoNotify when turning off
|
||||
from the same client
|
||||
|
||||
This fixes a use-after-free bug:
|
||||
|
||||
When a client first calls XvdiSelectVideoNotify() on a drawable with a
|
||||
TRUE onoff argument, a struct XvVideoNotifyRec is allocated. This struct
|
||||
is added twice to the resources:
|
||||
- as the drawable's XvRTVideoNotifyList. This happens only once per
|
||||
drawable, subsequent calls append to this list.
|
||||
- as the client's XvRTVideoNotify. This happens for every client.
|
||||
|
||||
The struct keeps the ClientPtr around once it has been added for a
|
||||
client. The idea, presumably, is that if the client disconnects we can remove
|
||||
all structs from the drawable's list that match the client (by resetting
|
||||
the ClientPtr to NULL), but if the drawable is destroyed we can remove
|
||||
and free the whole list.
|
||||
|
||||
However, if the same client then calls XvdiSelectVideoNotify() on the
|
||||
same drawable with a FALSE onoff argument, only the ClientPtr on the
|
||||
existing struct was set to NULL. The struct itself remained in the
|
||||
client's resources.
|
||||
|
||||
If the drawable is now destroyed, the resource system invokes
|
||||
XvdiDestroyVideoNotifyList which frees the whole list for this drawable
|
||||
- including our struct. This function however does not free the resource
|
||||
for the client since our ClientPtr is NULL.
|
||||
|
||||
Later, when the client is destroyed and the resource system invokes
|
||||
XvdiDestroyVideoNotify, we unconditionally set the ClientPtr to NULL. On
|
||||
a struct that has been freed previously. This is generally frowned upon.
|
||||
|
||||
Fix this by calling FreeResource() on the second call instead of merely
|
||||
setting the ClientPtr to NULL. This removes the struct from the client
|
||||
resources (but not from the list), ensuring that it won't be accessed
|
||||
again when the client quits.
|
||||
|
||||
Note that the assignment tpn->client = NULL; is superfluous since the
|
||||
XvdiDestroyVideoNotify function will do this anyway. But it's left for
|
||||
clarity and to match a similar invocation in XvdiSelectPortNotify.
|
||||
|
||||
CVE-2022-46342, ZDI-CAN 19400
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
---
|
||||
Xext/xvmain.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Xext/xvmain.c b/Xext/xvmain.c
|
||||
index f627471938..2a08f8744a 100644
|
||||
--- a/Xext/xvmain.c
|
||||
+++ b/Xext/xvmain.c
|
||||
@@ -811,8 +811,10 @@ XvdiSelectVideoNotify(ClientPtr client, DrawablePtr pDraw, BOOL onoff)
|
||||
tpn = pn;
|
||||
while (tpn) {
|
||||
if (tpn->client == client) {
|
||||
- if (!onoff)
|
||||
+ if (!onoff) {
|
||||
tpn->client = NULL;
|
||||
+ FreeResource(tpn->id, XvRTVideoNotify);
|
||||
+ }
|
||||
return Success;
|
||||
}
|
||||
if (!tpn->client)
|
||||
--
|
||||
2.38.1
|
|
@ -0,0 +1,73 @@
|
|||
From 01cd3a72858ccc1afb0b42ace92263f2912619a3 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jexposit@redhat.com>
|
||||
Date: Fri, 22 Dec 2023 18:28:31 +0100
|
||||
Subject: [PATCH xserver 6/9] Xi: do not keep linked list pointer during
|
||||
recursion
|
||||
|
||||
The `DisableDevice()` function is called whenever an enabled device
|
||||
is disabled and it moves the device from the `inputInfo.devices` linked
|
||||
list to the `inputInfo.off_devices` linked list.
|
||||
|
||||
However, its link/unlink operation has an issue during the recursive
|
||||
call to `DisableDevice()` due to the `prev` pointer pointing to a
|
||||
removed device.
|
||||
|
||||
This issue leads to a length mismatch between the total number of
|
||||
devices and the number of device in the list, leading to a heap
|
||||
overflow and, possibly, to local privilege escalation.
|
||||
|
||||
Simplify the code that checked whether the device passed to
|
||||
`DisableDevice()` was in `inputInfo.devices` or not and find the
|
||||
previous device after the recursion.
|
||||
|
||||
CVE-2024-21886, ZDI-CAN-22840
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
(cherry picked from commit bc1fdbe46559dd947674375946bbef54dd0ce36b)
|
||||
---
|
||||
dix/devices.c | 15 ++++++++++++---
|
||||
1 file changed, 12 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dix/devices.c b/dix/devices.c
|
||||
index 8fe4a341c..f3db37203 100644
|
||||
--- a/dix/devices.c
|
||||
+++ b/dix/devices.c
|
||||
@@ -453,14 +453,20 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
|
||||
{
|
||||
DeviceIntPtr *prev, other;
|
||||
BOOL enabled;
|
||||
+ BOOL dev_in_devices_list = FALSE;
|
||||
int flags[MAXDEVICES] = { 0 };
|
||||
|
||||
if (!dev->enabled)
|
||||
return TRUE;
|
||||
|
||||
- for (prev = &inputInfo.devices;
|
||||
- *prev && (*prev != dev); prev = &(*prev)->next);
|
||||
- if (*prev != dev)
|
||||
+ for (other = inputInfo.devices; other; other = other->next) {
|
||||
+ if (other == dev) {
|
||||
+ dev_in_devices_list = TRUE;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!dev_in_devices_list)
|
||||
return FALSE;
|
||||
|
||||
TouchEndPhysicallyActiveTouches(dev);
|
||||
@@ -511,6 +517,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
|
||||
LeaveWindow(dev);
|
||||
SetFocusOut(dev);
|
||||
|
||||
+ for (prev = &inputInfo.devices;
|
||||
+ *prev && (*prev != dev); prev = &(*prev)->next);
|
||||
+
|
||||
*prev = dev->next;
|
||||
dev->next = inputInfo.off_devices;
|
||||
inputInfo.off_devices = dev;
|
||||
--
|
||||
2.43.0
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
From 95224f0f92bc516983038a6326fba041cdef6e75 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Mon, 29 Mar 2021 14:22:56 +0200
|
||||
Subject: [PATCH xserver 06/27] xwayland/eglstream: Check buffer creation
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
EGLStream wl_eglstream_display_create_stream() may fail, yet Xwayland
|
||||
would try to attach the buffer which may cause a fatal Wayland protocol
|
||||
error raised by the compositor.
|
||||
|
||||
Check if the buffer creation worked, and fail gracefully otherwise (like
|
||||
wayland-eglsurface does).
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Martin Peres <martin.peres@mupuf.org>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
|
||||
(cherry picked from commit 4f0889e98306d30a37aba0fadb1fd3790c13205a)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 17295f3bd..c6e17bf8b 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -548,6 +548,10 @@ xwl_eglstream_create_pending_stream(struct xwl_screen *xwl_screen,
|
||||
stream_fd,
|
||||
WL_EGLSTREAM_HANDLE_TYPE_FD,
|
||||
&stream_attribs);
|
||||
+ if (!xwl_pixmap->buffer) {
|
||||
+ ErrorF("eglstream: Failed to create buffer\n");
|
||||
+ goto fail;
|
||||
+ }
|
||||
|
||||
wl_buffer_add_listener(xwl_pixmap->buffer,
|
||||
&xwl_eglstream_buffer_release_listener,
|
||||
@@ -562,7 +566,9 @@ xwl_eglstream_create_pending_stream(struct xwl_screen *xwl_screen,
|
||||
|
||||
xwl_eglstream_queue_pending_stream(xwl_screen, window, pixmap);
|
||||
|
||||
- close(stream_fd);
|
||||
+fail:
|
||||
+ if (stream_fd >= 0)
|
||||
+ close(stream_fd);
|
||||
}
|
||||
|
||||
static Bool
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
From 42f8d1828b4fc1e0b8165a767a0b74edcdbf3806 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Fri, 5 Jan 2024 09:40:27 +1000
|
||||
Subject: [PATCH xserver 7/9] dix: when disabling a master, float disabled
|
||||
slaved devices too
|
||||
|
||||
Disabling a master device floats all slave devices but we didn't do this
|
||||
to already-disabled slave devices. As a result those devices kept their
|
||||
reference to the master device resulting in access to already freed
|
||||
memory if the master device was removed before the corresponding slave
|
||||
device.
|
||||
|
||||
And to match this behavior, also forcibly reset that pointer during
|
||||
CloseDownDevices().
|
||||
|
||||
Related to CVE-2024-21886, ZDI-CAN-22840
|
||||
|
||||
(cherry picked from commit 26769aa71fcbe0a8403b7fb13b7c9010cc07c3a8)
|
||||
---
|
||||
dix/devices.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/dix/devices.c b/dix/devices.c
|
||||
index f3db37203..95190b5b7 100644
|
||||
--- a/dix/devices.c
|
||||
+++ b/dix/devices.c
|
||||
@@ -483,6 +483,13 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
|
||||
flags[other->id] |= XISlaveDetached;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ for (other = inputInfo.off_devices; other; other = other->next) {
|
||||
+ if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) {
|
||||
+ AttachDevice(NULL, other, NULL);
|
||||
+ flags[other->id] |= XISlaveDetached;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
else {
|
||||
for (other = inputInfo.devices; other; other = other->next) {
|
||||
@@ -1080,6 +1087,11 @@ CloseDownDevices(void)
|
||||
dev->master = NULL;
|
||||
}
|
||||
|
||||
+ for (dev = inputInfo.off_devices; dev; dev = dev->next) {
|
||||
+ if (!IsMaster(dev) && !IsFloating(dev))
|
||||
+ dev->master = NULL;
|
||||
+ }
|
||||
+
|
||||
CloseDeviceList(&inputInfo.devices);
|
||||
CloseDeviceList(&inputInfo.off_devices);
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
From 774260dbae1fa505cd2848c786baed9a8db5179d Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Mon, 5 Dec 2022 15:55:54 +1000
|
||||
Subject: [PATCH xserver 7/7] xkb: reset the radio_groups pointer to NULL after
|
||||
freeing it
|
||||
|
||||
Unlike other elements of the keymap, this pointer was freed but not
|
||||
reset. On a subsequent XkbGetKbdByName request, the server may access
|
||||
already freed memory.
|
||||
|
||||
CVE-2022-46283, ZDI-CAN-19530
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
---
|
||||
xkb/xkbUtils.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
|
||||
index dd089c2046..3f5791a183 100644
|
||||
--- a/xkb/xkbUtils.c
|
||||
+++ b/xkb/xkbUtils.c
|
||||
@@ -1326,6 +1326,7 @@ _XkbCopyNames(XkbDescPtr src, XkbDescPtr dst)
|
||||
}
|
||||
else {
|
||||
free(dst->names->radio_groups);
|
||||
+ dst->names->radio_groups = NULL;
|
||||
}
|
||||
dst->names->num_rg = src->names->num_rg;
|
||||
|
||||
--
|
||||
2.38.1
|
|
@ -1,88 +0,0 @@
|
|||
From 8a07b3e391bbed0b7d8f2ed37928b362eec3beee Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Mon, 29 Mar 2021 15:01:15 +0200
|
||||
Subject: [PATCH xserver 07/27] xwayland: Check buffer prior to attaching it
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If the buffer is NULL, do not even try to attach it, and risk a Wayland
|
||||
protocol error which would be fatal to us.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Martin Peres <martin.peres@mupuf.org>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
|
||||
(cherry picked from commit 25d2f4948f0abd39e099b8ac69b7cb1dab38a10a)
|
||||
---
|
||||
hw/xwayland/xwayland-cursor.c | 11 +++++++++--
|
||||
hw/xwayland/xwayland-present.c | 7 ++++++-
|
||||
hw/xwayland/xwayland-window.c | 5 +++++
|
||||
3 files changed, 20 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
|
||||
index fac8840e6..c4457cc2a 100644
|
||||
--- a/hw/xwayland/xwayland-cursor.c
|
||||
+++ b/hw/xwayland/xwayland-cursor.c
|
||||
@@ -162,8 +162,15 @@ static void
|
||||
xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat,
|
||||
struct xwl_cursor *xwl_cursor, PixmapPtr pixmap)
|
||||
{
|
||||
- wl_surface_attach(xwl_cursor->surface,
|
||||
- xwl_shm_pixmap_get_wl_buffer(pixmap), 0, 0);
|
||||
+ struct wl_buffer *buffer;
|
||||
+
|
||||
+ buffer = xwl_shm_pixmap_get_wl_buffer(pixmap);
|
||||
+ if (!buffer) {
|
||||
+ ErrorF("cursor: Error getting buffer\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ wl_surface_attach(xwl_cursor->surface, buffer, 0, 0);
|
||||
xwl_surface_damage(xwl_seat->xwl_screen, xwl_cursor->surface, 0, 0,
|
||||
xwl_seat->x_cursor->bits->width,
|
||||
xwl_seat->x_cursor->bits->height);
|
||||
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
|
||||
index 7ba7efc11..83d67517a 100644
|
||||
--- a/hw/xwayland/xwayland-present.c
|
||||
+++ b/hw/xwayland/xwayland-present.c
|
||||
@@ -443,6 +443,12 @@ xwl_present_flip(WindowPtr present_window,
|
||||
if (!xwl_window)
|
||||
return FALSE;
|
||||
|
||||
+ buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap);
|
||||
+ if (!buffer) {
|
||||
+ ErrorF("present: Error getting buffer\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
damage_box = RegionExtents(damage);
|
||||
|
||||
event = malloc(sizeof *event);
|
||||
@@ -450,7 +456,6 @@ xwl_present_flip(WindowPtr present_window,
|
||||
return FALSE;
|
||||
|
||||
pixmap->refcnt++;
|
||||
- buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap);
|
||||
|
||||
event->event_id = event_id;
|
||||
event->xwl_present_window = xwl_present_window;
|
||||
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
|
||||
index d0c7c581d..af4290ec7 100644
|
||||
--- a/hw/xwayland/xwayland-window.c
|
||||
+++ b/hw/xwayland/xwayland-window.c
|
||||
@@ -805,6 +805,11 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
|
||||
#endif
|
||||
buffer = xwl_shm_pixmap_get_wl_buffer(pixmap);
|
||||
|
||||
+ if (!buffer) {
|
||||
+ ErrorF("Error getting buffer\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
#ifdef XWL_HAS_GLAMOR
|
||||
if (xwl_screen->glamor)
|
||||
xwl_glamor_post_damage(xwl_window, pixmap, region);
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
From bb1711b7fba42f2a0c7d1c09beee241a1b2bcc30 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Mon, 19 Dec 2022 10:06:45 +1000
|
||||
Subject: [PATCH xserver] Xext: fix invalid event type mask in
|
||||
XTestSwapFakeInput
|
||||
|
||||
In commit b320ca0 the mask was inadvertently changed from octal 0177 to
|
||||
hexadecimal 0x177.
|
||||
|
||||
Fixes commit b320ca0ffe4c0c872eeb3a93d9bde21f765c7c63
|
||||
Xtest: disallow GenericEvents in XTestSwapFakeInput
|
||||
|
||||
Found by Stuart Cassoff
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
---
|
||||
Xext/xtest.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Xext/xtest.c b/Xext/xtest.c
|
||||
index 2985a4ce6e..dde5c4cf9d 100644
|
||||
--- a/Xext/xtest.c
|
||||
+++ b/Xext/xtest.c
|
||||
@@ -502,7 +502,7 @@ XTestSwapFakeInput(ClientPtr client, xReq * req)
|
||||
|
||||
nev = ((req->length << 2) - sizeof(xReq)) / sizeof(xEvent);
|
||||
for (ev = (xEvent *) &req[1]; --nev >= 0; ev++) {
|
||||
- int evtype = ev->u.u.type & 0x177;
|
||||
+ int evtype = ev->u.u.type & 0177;
|
||||
/* Swap event */
|
||||
proc = EventSwapVector[evtype];
|
||||
/* no swapping proc; invalid event type? */
|
||||
--
|
||||
2.38.1
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
From 85638273f23338d06776cdb7bb422440f690038a Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Tue, 30 Mar 2021 08:48:25 +0200
|
||||
Subject: [PATCH xserver 08/27] glamor: Dump backtrace on GL error
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Currrently, when a GL error is triggered, glamor would log the error
|
||||
which may not be sufficient to trace it back to the cause of the error.
|
||||
|
||||
Also dump the backtrace which may give more information as to where the
|
||||
error comes from.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Martin Peres <martin.peres@mupuf.org>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
|
||||
(cherry picked from commit 3b265c59a6456f6e4abfb9e1694237bc56f1776a)
|
||||
---
|
||||
glamor/glamor.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/glamor/glamor.c b/glamor/glamor.c
|
||||
index 3baef4b9f..b8406f42d 100644
|
||||
--- a/glamor/glamor.c
|
||||
+++ b/glamor/glamor.c
|
||||
@@ -414,6 +414,7 @@ glamor_debug_output_callback(GLenum source,
|
||||
|
||||
LogMessageVerb(X_ERROR, 0, "glamor%d: GL error: %*s\n",
|
||||
screen->myNum, length, message);
|
||||
+ xorg_backtrace();
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
From 4093057b98bc5a178f130c9ba6b0b28385e24ae5 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Wed, 6 Dec 2023 12:09:41 +0100
|
||||
Subject: [PATCH xserver 8/9] glx: Call XACE hooks on the GLX buffer
|
||||
|
||||
The XSELINUX code will label resources at creation by checking the
|
||||
access mode. When the access mode is DixCreateAccess, it will call the
|
||||
function to label the new resource SELinuxLabelResource().
|
||||
|
||||
However, GLX buffers do not go through the XACE hooks when created,
|
||||
hence leaving the resource actually unlabeled.
|
||||
|
||||
When, later, the client tries to create another resource using that
|
||||
drawable (like a GC for example), the XSELINUX code would try to use
|
||||
the security ID of that object which has never been labeled, get a NULL
|
||||
pointer and crash when checking whether the requested permissions are
|
||||
granted for subject security ID.
|
||||
|
||||
To avoid the issue, make sure to call the XACE hooks when creating the
|
||||
GLX buffers.
|
||||
|
||||
Credit goes to Donn Seeley <donn@xmission.com> for providing the patch.
|
||||
|
||||
CVE-2024-0408
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
(cherry picked from commit e5e8586a12a3ec915673edffa10dc8fe5e15dac3)
|
||||
---
|
||||
glx/glxcmds.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
|
||||
index fc26a2e34..1e46d0c72 100644
|
||||
--- a/glx/glxcmds.c
|
||||
+++ b/glx/glxcmds.c
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "indirect_util.h"
|
||||
#include "protocol-versions.h"
|
||||
#include "glxvndabi.h"
|
||||
+#include "xace.h"
|
||||
|
||||
static char GLXServerVendorName[] = "SGI";
|
||||
|
||||
@@ -1392,6 +1393,13 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
|
||||
if (!pPixmap)
|
||||
return BadAlloc;
|
||||
|
||||
+ err = XaceHook(XACE_RESOURCE_ACCESS, client, glxDrawableId, RT_PIXMAP,
|
||||
+ pPixmap, RT_NONE, NULL, DixCreateAccess);
|
||||
+ if (err != Success) {
|
||||
+ (*pGlxScreen->pScreen->DestroyPixmap) (pPixmap);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
/* Assign the pixmap the same id as the pbuffer and add it as a
|
||||
* resource so it and the DRI2 drawable will be reclaimed when the
|
||||
* pbuffer is destroyed. */
|
||||
--
|
||||
2.43.0
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
From 51be9e767a02cdc6a524dc895dcc81abb689d50b Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Wed, 6 Dec 2023 11:51:56 +0100
|
||||
Subject: [PATCH xserver 9/9] ephyr,xwayland: Use the proper private key for
|
||||
cursor
|
||||
|
||||
The cursor in DIX is actually split in two parts, the cursor itself and
|
||||
the cursor bits, each with their own devPrivates.
|
||||
|
||||
The cursor itself includes the cursor bits, meaning that the cursor bits
|
||||
devPrivates in within structure of the cursor.
|
||||
|
||||
Both Xephyr and Xwayland were using the private key for the cursor bits
|
||||
to store the data for the cursor, and when using XSELINUX which comes
|
||||
with its own special devPrivates, the data stored in that cursor bits'
|
||||
devPrivates would interfere with the XSELINUX devPrivates data and the
|
||||
SELINUX security ID would point to some other unrelated data, causing a
|
||||
crash in the XSELINUX code when trying to (re)use the security ID.
|
||||
|
||||
CVE-2024-0409
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
(cherry picked from commit 2ef0f1116c65d5cb06d7b6d83f8a1aea702c94f7)
|
||||
---
|
||||
hw/xwayland/xwayland-cursor.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
|
||||
index e3c1aaa50..bd94b0cfb 100644
|
||||
--- a/hw/xwayland/xwayland-cursor.c
|
||||
+++ b/hw/xwayland/xwayland-cursor.c
|
||||
@@ -431,7 +431,7 @@ static miPointerScreenFuncRec xwl_pointer_screen_funcs = {
|
||||
Bool
|
||||
xwl_screen_init_cursor(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
- if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR_BITS, 0))
|
||||
+ if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR, 0))
|
||||
return FALSE;
|
||||
|
||||
return miPointerInitialize(xwl_screen->screen,
|
||||
--
|
||||
2.43.0
|
||||
|
|
@ -1,125 +0,0 @@
|
|||
From c28bb0e879775aec83f5554522724eee592685dc Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Wed, 31 Mar 2021 13:57:45 +0200
|
||||
Subject: [PATCH xserver 09/27] xwayland/glamor: Add return status to
|
||||
post_damage
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If the glamor backend failed to post damage, the caller should do the
|
||||
same to avoid a failure to attach the buffer to the Wayland surface.
|
||||
|
||||
Change the API of Xwayland's glamor backend post_damage() to return a
|
||||
status so that xwl_window_post_damage() can tell whether the callee
|
||||
failed.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
|
||||
(cherry picked from commit 252cbad316f43edc08aa5c844789398a58ba270c)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 6 ++++--
|
||||
hw/xwayland/xwayland-glamor.c | 6 ++++--
|
||||
hw/xwayland/xwayland-glamor.h | 4 ++--
|
||||
hw/xwayland/xwayland-window.c | 8 ++++++--
|
||||
4 files changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index c6e17bf8b..f64d05064 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -605,7 +605,7 @@ xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
-static void
|
||||
+static Bool
|
||||
xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
|
||||
PixmapPtr pixmap, RegionPtr region)
|
||||
{
|
||||
@@ -625,7 +625,7 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
|
||||
* flipping OpenGL or Vulkan window. In that case, we don't
|
||||
* need to do the copy below.
|
||||
*/
|
||||
- return;
|
||||
+ return TRUE;
|
||||
|
||||
/* Unbind the framebuffer BEFORE binding the EGLSurface, otherwise we
|
||||
* won't actually draw to it
|
||||
@@ -668,6 +668,8 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
|
||||
|
||||
/* hang onto the pixmap until the compositor has released it */
|
||||
pixmap->refcnt++;
|
||||
+
|
||||
+ return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
|
||||
index 9e44d5106..e940f9fd7 100644
|
||||
--- a/hw/xwayland/xwayland-glamor.c
|
||||
+++ b/hw/xwayland/xwayland-glamor.c
|
||||
@@ -304,14 +304,16 @@ xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-void
|
||||
+Bool
|
||||
xwl_glamor_post_damage(struct xwl_window *xwl_window,
|
||||
PixmapPtr pixmap, RegionPtr region)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
|
||||
|
||||
if (xwl_screen->egl_backend->post_damage)
|
||||
- xwl_screen->egl_backend->post_damage(xwl_window, pixmap, region);
|
||||
+ return xwl_screen->egl_backend->post_damage(xwl_window, pixmap, region);
|
||||
+
|
||||
+ return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
|
||||
index 26ab78f04..cf3c4fba3 100644
|
||||
--- a/hw/xwayland/xwayland-glamor.h
|
||||
+++ b/hw/xwayland/xwayland-glamor.h
|
||||
@@ -83,7 +83,7 @@ struct xwl_egl_backend {
|
||||
* you should implement blitting from the glamor pixmap to the wayland
|
||||
* pixmap here. Otherwise, this callback is optional.
|
||||
*/
|
||||
- void (*post_damage)(struct xwl_window *xwl_window,
|
||||
+ Bool (*post_damage)(struct xwl_window *xwl_window,
|
||||
PixmapPtr pixmap, RegionPtr region);
|
||||
|
||||
/* Called by Xwayland to confirm with the egl backend that the given
|
||||
@@ -117,7 +117,7 @@ void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
|
||||
uint32_t version);
|
||||
Bool xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
|
||||
struct xwl_egl_backend *xwl_egl_backend);
|
||||
-void xwl_glamor_post_damage(struct xwl_window *xwl_window,
|
||||
+Bool xwl_glamor_post_damage(struct xwl_window *xwl_window,
|
||||
PixmapPtr pixmap, RegionPtr region);
|
||||
Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
|
||||
void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
|
||||
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
|
||||
index af4290ec7..00f161eda 100644
|
||||
--- a/hw/xwayland/xwayland-window.c
|
||||
+++ b/hw/xwayland/xwayland-window.c
|
||||
@@ -811,8 +811,12 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
|
||||
}
|
||||
|
||||
#ifdef XWL_HAS_GLAMOR
|
||||
- if (xwl_screen->glamor)
|
||||
- xwl_glamor_post_damage(xwl_window, pixmap, region);
|
||||
+ if (xwl_screen->glamor) {
|
||||
+ if (!xwl_glamor_post_damage(xwl_window, pixmap, region)) {
|
||||
+ ErrorF("glamor: Failed to post damage\n");
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
#endif
|
||||
|
||||
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
From 070abe64b15db831802a842aa1965403eb24679e Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Wed, 31 Mar 2021 09:49:35 +0200
|
||||
Subject: [PATCH xserver 10/27] xwayland/eglstream: Check framebuffer status
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The EGLStream backend would sometime generate GL errors trying to draw
|
||||
to the framebuffer, which gives an invalid buffer, which in turn would
|
||||
generate a Wayland error from the compositor which is fatal to the
|
||||
client.
|
||||
|
||||
Check the framebuffer status and bail out early if it's not complete,
|
||||
to avoid getting into trouble later.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
|
||||
(cherry picked from commit 85244d2a2081d61a2e4a06e847041f638de01e3f)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 18 ++++++++++++++----
|
||||
1 file changed, 14 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index f64d05064..64fe93b7c 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -619,6 +619,7 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
|
||||
box->x2 - box->x1, box->y2 - box->y1
|
||||
};
|
||||
GLint saved_vao;
|
||||
+ int status;
|
||||
|
||||
if (xwl_pixmap->type != XWL_PIXMAP_EGLSTREAM)
|
||||
/* This can happen if a client does X11 rendering on a
|
||||
@@ -652,6 +653,13 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
|
||||
glUniform1i(xwl_eglstream->blit_is_rgba_pos,
|
||||
pixmap->drawable.depth >= 32);
|
||||
|
||||
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
+ ErrorF("eglstream: Framebuffer incomplete 0x%X, not posting damage\n", status);
|
||||
+ status = FALSE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
/* Blit rendered image into EGLStream surface */
|
||||
glDrawBuffer(GL_BACK);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
@@ -662,14 +670,16 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
|
||||
else
|
||||
eglSwapBuffers(xwl_screen->egl_display, xwl_pixmap->surface);
|
||||
|
||||
+ /* hang onto the pixmap until the compositor has released it */
|
||||
+ pixmap->refcnt++;
|
||||
+ status = TRUE;
|
||||
+
|
||||
+out:
|
||||
/* Restore previous state */
|
||||
glBindVertexArray(saved_vao);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
- /* hang onto the pixmap until the compositor has released it */
|
||||
- pixmap->refcnt++;
|
||||
-
|
||||
- return TRUE;
|
||||
+ return status;
|
||||
}
|
||||
|
||||
static Bool
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
From 9966356963803db35997f26330fb1245777012a1 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Thu, 15 Apr 2021 10:59:36 +0200
|
||||
Subject: [PATCH xserver 11/27] xwayland/eglstream: Small refactoring
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Some functions are called "callback" whereas they are not longer
|
||||
callback functions or "unref" while they no longer deal with a reference
|
||||
counter anymore, which is quite confusing. Rename those functions to be
|
||||
more explicit.
|
||||
|
||||
Also, the pending streams can be destroyed in different places, move the
|
||||
common code to separate function to avoid duplicating code and help with
|
||||
readability of the code.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
(cherry picked from commit 823f3254fabd16e5e721da57cd260beac9b8f8bd)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 42 ++++++++++++++-----------
|
||||
1 file changed, 24 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 64fe93b7c..9abb7b779 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -287,7 +287,7 @@ xwl_glamor_egl_device_has_egl_extensions(void *device,
|
||||
}
|
||||
|
||||
static void
|
||||
-xwl_eglstream_unref_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
|
||||
+xwl_eglstream_destroy_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_pixmap->xwl_screen;
|
||||
|
||||
@@ -319,7 +319,17 @@ xwl_eglstream_unref_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
|
||||
}
|
||||
|
||||
static void
|
||||
-xwl_glamor_eglstream_del_pending_stream_cb(struct xwl_pixmap *xwl_pixmap)
|
||||
+xwl_glamor_eglstream_destroy_pending_stream(struct xwl_eglstream_pending_stream *pending)
|
||||
+{
|
||||
+ if (pending->cb)
|
||||
+ wl_callback_destroy(pending->cb);
|
||||
+ xwl_eglstream_window_set_pending(pending->window, NULL);
|
||||
+ xorg_list_del(&pending->link);
|
||||
+ free(pending);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+xwl_glamor_eglstream_remove_pending_stream(struct xwl_pixmap *xwl_pixmap)
|
||||
{
|
||||
struct xwl_eglstream_private *xwl_eglstream =
|
||||
xwl_eglstream_get(xwl_pixmap->xwl_screen);
|
||||
@@ -328,10 +338,7 @@ xwl_glamor_eglstream_del_pending_stream_cb(struct xwl_pixmap *xwl_pixmap)
|
||||
xorg_list_for_each_entry(pending,
|
||||
&xwl_eglstream->pending_streams, link) {
|
||||
if (pending->xwl_pixmap == xwl_pixmap) {
|
||||
- wl_callback_destroy(pending->cb);
|
||||
- xwl_eglstream_window_set_pending(pending->window, NULL);
|
||||
- xorg_list_del(&pending->link);
|
||||
- free(pending);
|
||||
+ xwl_glamor_eglstream_destroy_pending_stream(pending);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -343,9 +350,9 @@ xwl_glamor_eglstream_destroy_pixmap(PixmapPtr pixmap)
|
||||
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
|
||||
|
||||
if (xwl_pixmap && pixmap->refcnt == 1) {
|
||||
- xwl_glamor_eglstream_del_pending_stream_cb(xwl_pixmap);
|
||||
+ xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
|
||||
+ xwl_eglstream_destroy_pixmap_stream(xwl_pixmap);
|
||||
xwl_pixmap_del_buffer_release_cb(pixmap);
|
||||
- xwl_eglstream_unref_pixmap_stream(xwl_pixmap);
|
||||
}
|
||||
return glamor_destroy_pixmap(pixmap);
|
||||
}
|
||||
@@ -432,8 +439,6 @@ xwl_eglstream_consumer_ready_callback(void *data,
|
||||
struct xwl_eglstream_pending_stream *pending;
|
||||
Bool found = FALSE;
|
||||
|
||||
- wl_callback_destroy(callback);
|
||||
-
|
||||
xorg_list_for_each_entry(pending, &xwl_eglstream->pending_streams, link) {
|
||||
if (pending->cb == callback) {
|
||||
found = TRUE;
|
||||
@@ -442,8 +447,11 @@ xwl_eglstream_consumer_ready_callback(void *data,
|
||||
}
|
||||
assert(found);
|
||||
|
||||
+ wl_callback_destroy(callback);
|
||||
+ pending->cb = NULL;
|
||||
+
|
||||
if (!pending->is_valid) {
|
||||
- xwl_eglstream_unref_pixmap_stream(pending->xwl_pixmap);
|
||||
+ xwl_eglstream_destroy_pixmap_stream(pending->xwl_pixmap);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -462,9 +470,7 @@ xwl_eglstream_consumer_ready_callback(void *data,
|
||||
pending->window->drawable.id, pending->pixmap);
|
||||
|
||||
out:
|
||||
- xwl_eglstream_window_set_pending(pending->window, NULL);
|
||||
- xorg_list_del(&pending->link);
|
||||
- free(pending);
|
||||
+ xwl_glamor_eglstream_destroy_pending_stream(pending);
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener consumer_ready_listener = {
|
||||
@@ -514,8 +520,8 @@ static const struct wl_buffer_listener xwl_eglstream_buffer_release_listener = {
|
||||
};
|
||||
|
||||
static void
|
||||
-xwl_eglstream_create_pending_stream(struct xwl_screen *xwl_screen,
|
||||
- WindowPtr window, PixmapPtr pixmap)
|
||||
+xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
|
||||
+ WindowPtr window, PixmapPtr pixmap)
|
||||
{
|
||||
struct xwl_eglstream_private *xwl_eglstream =
|
||||
xwl_eglstream_get(xwl_screen);
|
||||
@@ -599,8 +605,8 @@ xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
|
||||
/* Glamor pixmap has no backing stream yet; begin making one and disallow
|
||||
* commits until then
|
||||
*/
|
||||
- xwl_eglstream_create_pending_stream(xwl_screen, xwl_window->window,
|
||||
- pixmap);
|
||||
+ xwl_eglstream_create_pixmap_and_stream(xwl_screen, xwl_window->window,
|
||||
+ pixmap);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,150 +0,0 @@
|
|||
From e8f7568016249822bb95c87447ded6abb724c13b Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Thu, 1 Apr 2021 08:46:52 +0200
|
||||
Subject: [PATCH xserver 12/27] xwayland/eglstream: Add more error checking
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
eglCreateStreamKHR() can fail and return EGL_NO_STREAM_KHR, in which
|
||||
case there is no point in trying to create a buffer from it.
|
||||
|
||||
Similarly, eglCreateStreamProducerSurfaceKHR() also fail and return
|
||||
EGL_NO_SURFACE, which in turn will be used in eglMakeCurrent() as
|
||||
draw/read surface, and therefore would mean no draw/read buffer.
|
||||
|
||||
In those cases, log the error, and bail out early. That won't solve the
|
||||
issue but will help with investigating the root cause of issues with
|
||||
EGLStream backend.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
|
||||
(cherry picked from commit cc596bcfb273eeab82ac3d59867668af8bad2abf)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 93 +++++++++++++++++++++++++
|
||||
1 file changed, 93 insertions(+)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 9abb7b779..77b24a4b4 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -387,6 +387,84 @@ xwl_eglstream_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
|
||||
xwl_screen->screen->SetWindowPixmap = xwl_eglstream_set_window_pixmap;
|
||||
}
|
||||
|
||||
+static const char *
|
||||
+xwl_eglstream_get_error_str(EGLint error)
|
||||
+{
|
||||
+ switch (error) {
|
||||
+ case EGL_BAD_PARAMETER:
|
||||
+ return "EGL_BAD_PARAMETER";
|
||||
+ case EGL_BAD_ATTRIBUTE:
|
||||
+ return "EGL_BAD_ATTRIBUTE";
|
||||
+ case EGL_BAD_MATCH:
|
||||
+ return "EGL_BAD_MATCH";
|
||||
+ case EGL_BAD_ACCESS:
|
||||
+ return "EGL_BAD_ACCESS";
|
||||
+ case EGL_BAD_STATE_KHR:
|
||||
+ return "EGL_BAD_STATE_KHR";
|
||||
+ case EGL_BAD_STREAM_KHR:
|
||||
+ return "EGL_BAD_STREAM_KHR";
|
||||
+ case EGL_BAD_DISPLAY:
|
||||
+ return "EGL_BAD_DISPLAY";
|
||||
+ case EGL_NOT_INITIALIZED:
|
||||
+ return "EGL_NOT_INITIALIZED";
|
||||
+ default:
|
||||
+ return "Unknown error";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const char *
|
||||
+xwl_eglstream_get_stream_state_str(EGLint state)
|
||||
+{
|
||||
+ switch (state) {
|
||||
+ case EGL_STREAM_STATE_CREATED_KHR:
|
||||
+ return "EGL_STREAM_STATE_CREATED_KHR";
|
||||
+ case EGL_STREAM_STATE_CONNECTING_KHR:
|
||||
+ return "EGL_STREAM_STATE_CONNECTING_KHR";
|
||||
+ case EGL_STREAM_STATE_EMPTY_KHR:
|
||||
+ return "EGL_STREAM_STATE_EMPTY_KHR";
|
||||
+ case EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR:
|
||||
+ return "EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR";
|
||||
+ case EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR:
|
||||
+ return "EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR";
|
||||
+ case EGL_STREAM_STATE_DISCONNECTED_KHR:
|
||||
+ return "EGL_STREAM_STATE_DISCONNECTED_KHR";
|
||||
+ default:
|
||||
+ return "Unknown state";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static EGLint
|
||||
+xwl_eglstream_get_state(EGLDisplay egl_display, EGLStreamKHR egl_stream)
|
||||
+{
|
||||
+ EGLint state;
|
||||
+
|
||||
+ eglQueryStreamKHR(egl_display, egl_stream, EGL_STREAM_STATE_KHR, &state);
|
||||
+ if (!eglQueryStreamKHR(egl_display, egl_stream,
|
||||
+ EGL_STREAM_STATE_KHR, &state)) {
|
||||
+ EGLint state_error = eglGetError();
|
||||
+ ErrorF("eglstream: Failed to query state - error 0x%X: %s\n",
|
||||
+ state_error, xwl_eglstream_get_error_str(state_error));
|
||||
+ return EGL_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return state;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void
|
||||
+xwl_eglstream_print_error(EGLDisplay egl_display,
|
||||
+ EGLStreamKHR egl_stream, EGLint error)
|
||||
+{
|
||||
+ ErrorF("eglstream: error 0x%X: %s\n", error,
|
||||
+ xwl_eglstream_get_error_str(error));
|
||||
+
|
||||
+ if (error == EGL_BAD_STATE_KHR) {
|
||||
+ EGLint state = xwl_eglstream_get_state(egl_display, egl_stream);
|
||||
+ ErrorF("eglstream: stream state 0x%X: %s\n", state,
|
||||
+ xwl_eglstream_get_stream_state_str(state));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* 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
|
||||
@@ -466,6 +544,13 @@ xwl_eglstream_consumer_ready_callback(void *data,
|
||||
EGL_NONE
|
||||
});
|
||||
|
||||
+ if (xwl_pixmap->surface == EGL_NO_SURFACE) {
|
||||
+ ErrorF("eglstream: Failed to create EGLSurface for pixmap\n");
|
||||
+ xwl_eglstream_print_error(xwl_screen->egl_display,
|
||||
+ xwl_pixmap->stream, eglGetError());
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
DebugF("eglstream: win %d completes eglstream for pixmap %p, congrats!\n",
|
||||
pending->window->drawable.id, pending->pixmap);
|
||||
|
||||
@@ -543,8 +628,16 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
|
||||
xwl_pixmap->xwl_screen = xwl_screen;
|
||||
xwl_pixmap->surface = EGL_NO_SURFACE;
|
||||
xwl_pixmap->stream = eglCreateStreamKHR(xwl_screen->egl_display, NULL);
|
||||
+ if (xwl_pixmap->stream == EGL_NO_STREAM_KHR) {
|
||||
+ ErrorF("eglstream: Couldn't create EGL stream.\n");
|
||||
+ goto fail;
|
||||
+ }
|
||||
stream_fd = eglGetStreamFileDescriptorKHR(xwl_screen->egl_display,
|
||||
xwl_pixmap->stream);
|
||||
+ if (stream_fd == EGL_NO_FILE_DESCRIPTOR_KHR) {
|
||||
+ ErrorF("eglstream: Couldn't get EGL stream file descriptor.\n");
|
||||
+ goto fail;
|
||||
+ }
|
||||
|
||||
wl_array_init(&stream_attribs);
|
||||
xwl_pixmap->buffer =
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,323 +0,0 @@
|
|||
From 90188c2648edb137f3564bdea53012355473f105 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Fri, 16 Apr 2021 10:38:23 +0200
|
||||
Subject: [PATCH xserver 13/27] xwayland/eglstream: Dissociate pending stream
|
||||
from window
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Previously, we would have pending streams associated with top level X11
|
||||
windows, keeping temporary accounting for the pending streams before
|
||||
they get fully initialized for the xwl_pixmap which would be associated
|
||||
with X11 pixmaps.
|
||||
|
||||
If the window content changes before the stream is ready, the
|
||||
corresponding pending stream would be marked as invalid and the pending
|
||||
stream would be eventually removed once the stream becomes ready.
|
||||
|
||||
Since commit affc47452 - "xwayland: Drop the separate refcount for the
|
||||
xwl_pixmap", we no longer keep a separate reference counter for the
|
||||
xwl_pixmap, but rather tie it to the X11 pixmap lifespan. Yet, the
|
||||
pending stream would still be associated with the X11 toplevel window.
|
||||
|
||||
Dissociate the pending streams from the X11 toplevel window, to keep it
|
||||
tied only to the xwl_pixmap so that we can have:
|
||||
|
||||
- pixmap <-> xwl_pixmap
|
||||
- xwl_pixmap <-> pending stream
|
||||
|
||||
Of course, the pending streams remain temporary and get removed as soon
|
||||
as the ready callback is triggered, but the pending streams are not
|
||||
linked to the X11 window anymore which can change their content, and
|
||||
therefore their X11 pixmap at any time.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
|
||||
(cherry picked from commit cb61ecc7291cfbed2f76d4437cd7450b8e4dab00)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 131 +++++++++++-------------
|
||||
1 file changed, 60 insertions(+), 71 deletions(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 77b24a4b4..32f9a326f 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -93,6 +93,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;
|
||||
|
||||
/* XWL_PIXMAP_EGLSTREAM. */
|
||||
EGLStreamKHR stream;
|
||||
@@ -103,7 +104,6 @@ struct xwl_pixmap {
|
||||
};
|
||||
|
||||
static DevPrivateKeyRec xwl_eglstream_private_key;
|
||||
-static DevPrivateKeyRec xwl_eglstream_window_private_key;
|
||||
|
||||
static inline struct xwl_eglstream_private *
|
||||
xwl_eglstream_get(struct xwl_screen *xwl_screen)
|
||||
@@ -112,21 +112,6 @@ xwl_eglstream_get(struct xwl_screen *xwl_screen)
|
||||
&xwl_eglstream_private_key);
|
||||
}
|
||||
|
||||
-static inline struct xwl_eglstream_pending_stream *
|
||||
-xwl_eglstream_window_get_pending(WindowPtr window)
|
||||
-{
|
||||
- return dixLookupPrivate(&window->devPrivates,
|
||||
- &xwl_eglstream_window_private_key);
|
||||
-}
|
||||
-
|
||||
-static inline void
|
||||
-xwl_eglstream_window_set_pending(WindowPtr window,
|
||||
- struct xwl_eglstream_pending_stream *stream)
|
||||
-{
|
||||
- dixSetPrivate(&window->devPrivates,
|
||||
- &xwl_eglstream_window_private_key, stream);
|
||||
-}
|
||||
-
|
||||
static GLint
|
||||
xwl_eglstream_compile_glsl_prog(GLenum type, const char *source)
|
||||
{
|
||||
@@ -323,7 +308,6 @@ xwl_glamor_eglstream_destroy_pending_stream(struct xwl_eglstream_pending_stream
|
||||
{
|
||||
if (pending->cb)
|
||||
wl_callback_destroy(pending->cb);
|
||||
- xwl_eglstream_window_set_pending(pending->window, NULL);
|
||||
xorg_list_del(&pending->link);
|
||||
free(pending);
|
||||
}
|
||||
@@ -331,16 +315,9 @@ xwl_glamor_eglstream_destroy_pending_stream(struct xwl_eglstream_pending_stream
|
||||
static void
|
||||
xwl_glamor_eglstream_remove_pending_stream(struct xwl_pixmap *xwl_pixmap)
|
||||
{
|
||||
- struct xwl_eglstream_private *xwl_eglstream =
|
||||
- xwl_eglstream_get(xwl_pixmap->xwl_screen);
|
||||
- struct xwl_eglstream_pending_stream *pending;
|
||||
-
|
||||
- xorg_list_for_each_entry(pending,
|
||||
- &xwl_eglstream->pending_streams, link) {
|
||||
- if (pending->xwl_pixmap == xwl_pixmap) {
|
||||
- xwl_glamor_eglstream_destroy_pending_stream(pending);
|
||||
- break;
|
||||
- }
|
||||
+ if (xwl_pixmap->pending_stream) {
|
||||
+ xwl_glamor_eglstream_destroy_pending_stream(xwl_pixmap->pending_stream);
|
||||
+ xwl_pixmap->pending_stream = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,23 +340,41 @@ xwl_glamor_eglstream_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
|
||||
return xwl_pixmap_get(pixmap)->buffer;
|
||||
}
|
||||
|
||||
+static void
|
||||
+xwl_eglstream_maybe_set_pending_stream_invalid(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;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
xwl_eglstream_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
|
||||
{
|
||||
- struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen);
|
||||
+ ScreenPtr screen = window->drawable.pScreen;
|
||||
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
struct xwl_eglstream_private *xwl_eglstream =
|
||||
xwl_eglstream_get(xwl_screen);
|
||||
- struct xwl_eglstream_pending_stream *pending;
|
||||
+ PixmapPtr old_pixmap;
|
||||
|
||||
- pending = xwl_eglstream_window_get_pending(window);
|
||||
- if (pending) {
|
||||
- /* The pixmap for this window has changed before the compositor
|
||||
- * finished attaching the consumer for the window's pixmap's original
|
||||
- * eglstream. A producer can no longer be attached, so the stream's
|
||||
- * useless
|
||||
- */
|
||||
- pending->is_valid = FALSE;
|
||||
- }
|
||||
+ /* The pixmap for this window has changed.
|
||||
+ * If that occurs while there is a stream pending, i.e. before the
|
||||
+ * compositor has finished attaching the consumer for the window's
|
||||
+ * pixmap's original eglstream, then a producer could no longer be
|
||||
+ * attached, so the stream would be useless.
|
||||
+ */
|
||||
+ old_pixmap = (*screen->GetWindowPixmap) (window);
|
||||
+ if (old_pixmap)
|
||||
+ xwl_eglstream_maybe_set_pending_stream_invalid(old_pixmap);
|
||||
|
||||
xwl_screen->screen->SetWindowPixmap = xwl_eglstream->SetWindowPixmap;
|
||||
(*xwl_screen->screen->SetWindowPixmap)(window, pixmap);
|
||||
@@ -489,16 +484,18 @@ xwl_eglstream_print_error(EGLDisplay egl_display,
|
||||
* - 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 queue of pending streams, and
|
||||
- * only allowing one queue entry to exist for each window. In the scenario
|
||||
- * listed above, this should happen:
|
||||
+ * 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, causing us to add an eglstream (known as eglstream
|
||||
- * A) waiting for its consumer to finish attachment to be added to the
|
||||
- * queue.
|
||||
+ * - 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 and add another one to the pending queue (known as eglstream B).
|
||||
+ * 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.
|
||||
@@ -515,6 +512,7 @@ xwl_eglstream_consumer_ready_callback(void *data,
|
||||
xwl_eglstream_get(xwl_screen);
|
||||
struct xwl_pixmap *xwl_pixmap;
|
||||
struct xwl_eglstream_pending_stream *pending;
|
||||
+ PixmapPtr pixmap;
|
||||
Bool found = FALSE;
|
||||
|
||||
xorg_list_for_each_entry(pending, &xwl_eglstream->pending_streams, link) {
|
||||
@@ -528,6 +526,9 @@ xwl_eglstream_consumer_ready_callback(void *data,
|
||||
wl_callback_destroy(callback);
|
||||
pending->cb = NULL;
|
||||
|
||||
+ xwl_pixmap = pending->xwl_pixmap;
|
||||
+ pixmap = pending->pixmap;
|
||||
+
|
||||
if (!pending->is_valid) {
|
||||
xwl_eglstream_destroy_pixmap_stream(pending->xwl_pixmap);
|
||||
goto out;
|
||||
@@ -535,12 +536,11 @@ xwl_eglstream_consumer_ready_callback(void *data,
|
||||
|
||||
xwl_glamor_egl_make_current(xwl_screen);
|
||||
|
||||
- xwl_pixmap = pending->xwl_pixmap;
|
||||
xwl_pixmap->surface = eglCreateStreamProducerSurfaceKHR(
|
||||
xwl_screen->egl_display, xwl_eglstream->config,
|
||||
xwl_pixmap->stream, (int[]) {
|
||||
- EGL_WIDTH, pending->pixmap->drawable.width,
|
||||
- EGL_HEIGHT, pending->pixmap->drawable.height,
|
||||
+ EGL_WIDTH, pixmap->drawable.width,
|
||||
+ EGL_HEIGHT, pixmap->drawable.height,
|
||||
EGL_NONE
|
||||
});
|
||||
|
||||
@@ -555,14 +555,14 @@ xwl_eglstream_consumer_ready_callback(void *data,
|
||||
pending->window->drawable.id, pending->pixmap);
|
||||
|
||||
out:
|
||||
- xwl_glamor_eglstream_destroy_pending_stream(pending);
|
||||
+ xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener consumer_ready_listener = {
|
||||
xwl_eglstream_consumer_ready_callback
|
||||
};
|
||||
|
||||
-static void
|
||||
+static struct xwl_eglstream_pending_stream *
|
||||
xwl_eglstream_queue_pending_stream(struct xwl_screen *xwl_screen,
|
||||
WindowPtr window, PixmapPtr pixmap)
|
||||
{
|
||||
@@ -570,14 +570,8 @@ xwl_eglstream_queue_pending_stream(struct xwl_screen *xwl_screen,
|
||||
xwl_eglstream_get(xwl_screen);
|
||||
struct xwl_eglstream_pending_stream *pending_stream;
|
||||
|
||||
-#ifdef DEBUG
|
||||
- if (!xwl_eglstream_window_get_pending(window))
|
||||
- DebugF("eglstream: win %d begins new eglstream for pixmap %p\n",
|
||||
- window->drawable.id, pixmap);
|
||||
- else
|
||||
- DebugF("eglstream: win %d interrupts and replaces pending eglstream for pixmap %p\n",
|
||||
- window->drawable.id, pixmap);
|
||||
-#endif
|
||||
+ DebugF("eglstream: win %d queues new pending stream for pixmap %p\n",
|
||||
+ window->drawable.id, pixmap);
|
||||
|
||||
pending_stream = malloc(sizeof(*pending_stream));
|
||||
pending_stream->window = window;
|
||||
@@ -586,11 +580,12 @@ xwl_eglstream_queue_pending_stream(struct xwl_screen *xwl_screen,
|
||||
pending_stream->is_valid = TRUE;
|
||||
xorg_list_init(&pending_stream->link);
|
||||
xorg_list_add(&pending_stream->link, &xwl_eglstream->pending_streams);
|
||||
- xwl_eglstream_window_set_pending(window, pending_stream);
|
||||
|
||||
pending_stream->cb = wl_display_sync(xwl_screen->display);
|
||||
wl_callback_add_listener(pending_stream->cb, &consumer_ready_listener,
|
||||
xwl_screen);
|
||||
+
|
||||
+ return pending_stream;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -663,7 +658,8 @@ 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_eglstream_queue_pending_stream(xwl_screen, window, pixmap);
|
||||
+ xwl_pixmap->pending_stream =
|
||||
+ xwl_eglstream_queue_pending_stream(xwl_screen, window, pixmap);
|
||||
|
||||
fail:
|
||||
if (stream_fd >= 0)
|
||||
@@ -674,22 +670,19 @@ static Bool
|
||||
xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
|
||||
- struct xwl_eglstream_pending_stream *pending =
|
||||
- xwl_eglstream_window_get_pending(xwl_window->window);
|
||||
PixmapPtr pixmap =
|
||||
(*xwl_screen->screen->GetWindowPixmap)(xwl_window->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) {
|
||||
/* Wait for the compositor to finish connecting the consumer for
|
||||
* this eglstream */
|
||||
- if (pending->is_valid)
|
||||
- return FALSE;
|
||||
+ assert(pending->is_valid);
|
||||
|
||||
- /* The pixmap for this window was changed before the compositor
|
||||
- * finished connecting the eglstream for the window's previous
|
||||
- * pixmap. Begin creating a new eglstream. */
|
||||
+ return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1190,10 +1183,6 @@ xwl_glamor_eglstream_init_screen(struct xwl_screen *xwl_screen)
|
||||
xwl_eglstream->SetWindowPixmap = screen->SetWindowPixmap;
|
||||
screen->SetWindowPixmap = xwl_eglstream_set_window_pixmap;
|
||||
|
||||
- if (!dixRegisterPrivateKey(&xwl_eglstream_window_private_key,
|
||||
- PRIVATE_WINDOW, 0))
|
||||
- return FALSE;
|
||||
-
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
From f76dd86f5bbdccb3655ac58365e4604d03de65f5 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Wed, 14 Apr 2021 17:31:08 +0200
|
||||
Subject: [PATCH xserver 14/27] xwayland/eglstream: Keep a reference to the
|
||||
pixmap
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Commit affc47452 - "xwayland: Drop the separate refcount for the
|
||||
xwl_pixmap" removed the separate reference counter for the xwl_pixmap
|
||||
which holds the EGLStream.
|
||||
|
||||
While that works fine for the common case, if the window's pixmap is
|
||||
changed before the stream is ready, the older pixmap will be destroyed
|
||||
and the xwl_pixmap along with it, even if the compositor is still using
|
||||
the stream.
|
||||
|
||||
The code that was removed with commit affc47452 was taking care of that
|
||||
by increasing the separate reference counter for the xwl_pixmap, but it
|
||||
no longer the case.
|
||||
|
||||
As a result, we may end up with the EGL stream in the wrong state when
|
||||
trying to use it, which will cascade down into all sort of issues.
|
||||
|
||||
To avoid the problem, increase the reference count on the pixmap when it
|
||||
is marked as invalid in EGLStream's SetWindowPixmap().
|
||||
|
||||
This way, the xwl_pixmap and the EGLStream are kept until released by
|
||||
the compositor, even when the pixmap changes before stream is ready.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
Fixes: affc47452 xwayland: Drop the separate refcount for the xwl_pixmap
|
||||
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
|
||||
(cherry picked from commit e19bf86c17ef9c802fea24410cc6b1f51a19ce7f)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 32f9a326f..807bfcb1d 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -355,6 +355,13 @@ xwl_eglstream_maybe_set_pending_stream_invalid(PixmapPtr pixmap)
|
||||
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++;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -530,8 +537,9 @@ xwl_eglstream_consumer_ready_callback(void *data,
|
||||
pixmap = pending->pixmap;
|
||||
|
||||
if (!pending->is_valid) {
|
||||
- xwl_eglstream_destroy_pixmap_stream(pending->xwl_pixmap);
|
||||
- goto out;
|
||||
+ xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
|
||||
+ dixDestroyPixmap(pixmap, 0);
|
||||
+ return;
|
||||
}
|
||||
|
||||
xwl_glamor_egl_make_current(xwl_screen);
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
From a68e939342aed0ea11c737d166e506442e048e90 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Tue, 27 Apr 2021 14:17:19 +0200
|
||||
Subject: [PATCH xserver 15/27] xwayland/eglstream: Drop the list of pending
|
||||
streams
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Now that the pending stream is associated with the xwl_pixmap for
|
||||
EGLStream and the xwl_pixmap itself is associated to the pixmap, we have
|
||||
a reliable way to get to those data from any pending stream.
|
||||
|
||||
As a result, the list of pending streams that we keep in the EGLStream
|
||||
global structure becomes useless.
|
||||
|
||||
So we can drop the pending stream's xwl_pixmap and also the list of
|
||||
pending streams altogether, and save us a walk though that list for each
|
||||
callback.
|
||||
|
||||
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 bee2ebb29f0999862ab39af26c673c00af40b082)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 41 ++++++-------------------
|
||||
1 file changed, 9 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 807bfcb1d..399a691d3 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -55,12 +55,9 @@ struct xwl_eglstream_pending_stream {
|
||||
PixmapPtr pixmap;
|
||||
WindowPtr window;
|
||||
|
||||
- struct xwl_pixmap *xwl_pixmap;
|
||||
struct wl_callback *cb;
|
||||
|
||||
Bool is_valid;
|
||||
-
|
||||
- struct xorg_list link;
|
||||
};
|
||||
|
||||
struct xwl_eglstream_private {
|
||||
@@ -73,8 +70,6 @@ struct xwl_eglstream_private {
|
||||
|
||||
SetWindowPixmapProcPtr SetWindowPixmap;
|
||||
|
||||
- struct xorg_list pending_streams;
|
||||
-
|
||||
Bool have_egl_damage;
|
||||
|
||||
GLint blit_prog;
|
||||
@@ -308,7 +303,6 @@ xwl_glamor_eglstream_destroy_pending_stream(struct xwl_eglstream_pending_stream
|
||||
{
|
||||
if (pending->cb)
|
||||
wl_callback_destroy(pending->cb);
|
||||
- xorg_list_del(&pending->link);
|
||||
free(pending);
|
||||
}
|
||||
|
||||
@@ -514,28 +508,16 @@ xwl_eglstream_consumer_ready_callback(void *data,
|
||||
struct wl_callback *callback,
|
||||
uint32_t time)
|
||||
{
|
||||
- struct xwl_screen *xwl_screen = data;
|
||||
+ struct xwl_eglstream_pending_stream *pending = data;
|
||||
+ PixmapPtr pixmap = pending->pixmap;
|
||||
+ 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);
|
||||
- struct xwl_pixmap *xwl_pixmap;
|
||||
- struct xwl_eglstream_pending_stream *pending;
|
||||
- PixmapPtr pixmap;
|
||||
- Bool found = FALSE;
|
||||
-
|
||||
- xorg_list_for_each_entry(pending, &xwl_eglstream->pending_streams, link) {
|
||||
- if (pending->cb == callback) {
|
||||
- found = TRUE;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- assert(found);
|
||||
|
||||
wl_callback_destroy(callback);
|
||||
pending->cb = NULL;
|
||||
|
||||
- xwl_pixmap = pending->xwl_pixmap;
|
||||
- pixmap = pending->pixmap;
|
||||
-
|
||||
if (!pending->is_valid) {
|
||||
xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
|
||||
dixDestroyPixmap(pixmap, 0);
|
||||
@@ -571,11 +553,10 @@ static const struct wl_callback_listener consumer_ready_listener = {
|
||||
};
|
||||
|
||||
static struct xwl_eglstream_pending_stream *
|
||||
-xwl_eglstream_queue_pending_stream(struct xwl_screen *xwl_screen,
|
||||
- WindowPtr window, PixmapPtr pixmap)
|
||||
+xwl_eglstream_queue_pending_stream(WindowPtr window, PixmapPtr pixmap)
|
||||
{
|
||||
- struct xwl_eglstream_private *xwl_eglstream =
|
||||
- xwl_eglstream_get(xwl_screen);
|
||||
+ 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",
|
||||
@@ -584,14 +565,11 @@ xwl_eglstream_queue_pending_stream(struct xwl_screen *xwl_screen,
|
||||
pending_stream = malloc(sizeof(*pending_stream));
|
||||
pending_stream->window = window;
|
||||
pending_stream->pixmap = pixmap;
|
||||
- pending_stream->xwl_pixmap = xwl_pixmap_get(pixmap);
|
||||
pending_stream->is_valid = TRUE;
|
||||
- xorg_list_init(&pending_stream->link);
|
||||
- xorg_list_add(&pending_stream->link, &xwl_eglstream->pending_streams);
|
||||
|
||||
pending_stream->cb = wl_display_sync(xwl_screen->display);
|
||||
wl_callback_add_listener(pending_stream->cb, &consumer_ready_listener,
|
||||
- xwl_screen);
|
||||
+ pending_stream);
|
||||
|
||||
return pending_stream;
|
||||
}
|
||||
@@ -667,7 +645,7 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
|
||||
xwl_eglstream->controller, xwl_window->surface, xwl_pixmap->buffer);
|
||||
|
||||
xwl_pixmap->pending_stream =
|
||||
- xwl_eglstream_queue_pending_stream(xwl_screen, window, pixmap);
|
||||
+ xwl_eglstream_queue_pending_stream(window, pixmap);
|
||||
|
||||
fail:
|
||||
if (stream_fd >= 0)
|
||||
@@ -1249,7 +1227,6 @@ xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
|
||||
&xwl_eglstream_private_key, xwl_eglstream);
|
||||
|
||||
xwl_eglstream->egl_device = egl_device;
|
||||
- xorg_list_init(&xwl_eglstream->pending_streams);
|
||||
|
||||
xwl_screen->eglstream_backend.init_egl = xwl_glamor_eglstream_init_egl;
|
||||
xwl_screen->eglstream_backend.init_wl_registry = xwl_glamor_eglstream_init_wl_registry;
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
From 9601f2cc5c94b9db4c7f8da404dae53b9609c995 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Mon, 19 Apr 2021 18:11:19 +0200
|
||||
Subject: [PATCH xserver 16/27] xwayland/eglstream: Do not commit without
|
||||
surface
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The EGL surface for the xwl_pixmap is created once the stream is ready
|
||||
and valid.
|
||||
|
||||
If the pixmap's EGL surface fails, for whatever reason, the xwl_pixmap
|
||||
will be unusable and will end up as an invalid wl_buffer.
|
||||
|
||||
Make sure we do not allow commits in that case and recreate the
|
||||
xwl_pixmap/stream.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
|
||||
(cherry picked from commit 098e0f52c088c6eb52c7e54c5a11cefabd480908)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 399a691d3..ce066cd9e 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -670,7 +670,14 @@ xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
|
||||
|
||||
return FALSE;
|
||||
} else {
|
||||
- return TRUE;
|
||||
+ if (xwl_pixmap->surface != EGL_NO_SURFACE)
|
||||
+ 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);
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
From 39df6934d5a9a132c2e87456e35094b7e81a238e Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Mon, 19 Apr 2021 14:52:38 +0200
|
||||
Subject: [PATCH xserver 17/27] xwayland/eglstream: Fix calloc/malloc
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Use calloc() instead of malloc() like the rest of the code.
|
||||
|
||||
Also fix the arguments of calloc() calls to match the definition which
|
||||
is calloc(size_t nmemb, size_t size).
|
||||
|
||||
This is a cleanup patch, no functional change.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
(cherry picked from commit a45799971083c47082d085d3732a5b12692cf75b)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index ce066cd9e..3a3caa976 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -562,7 +562,7 @@ xwl_eglstream_queue_pending_stream(WindowPtr window, PixmapPtr pixmap)
|
||||
DebugF("eglstream: win %d queues new pending stream for pixmap %p\n",
|
||||
window->drawable.id, pixmap);
|
||||
|
||||
- pending_stream = malloc(sizeof(*pending_stream));
|
||||
+ pending_stream = calloc(1, sizeof(*pending_stream));
|
||||
pending_stream->window = window;
|
||||
pending_stream->pixmap = pixmap;
|
||||
pending_stream->is_valid = TRUE;
|
||||
@@ -596,7 +596,7 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
|
||||
struct wl_array stream_attribs;
|
||||
int stream_fd = -1;
|
||||
|
||||
- xwl_pixmap = calloc(sizeof(*xwl_pixmap), 1);
|
||||
+ xwl_pixmap = calloc(1, sizeof(*xwl_pixmap));
|
||||
if (!xwl_pixmap)
|
||||
FatalError("Not enough memory to create pixmap\n");
|
||||
xwl_pixmap_set_private(pixmap, xwl_pixmap);
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
From a964ccdadf351d90482df00c272dee3634f7a8ee Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Fri, 30 Apr 2021 09:02:29 +0200
|
||||
Subject: [PATCH xserver 18/27] xwayland/eglstream: Check eglSwapBuffers()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
EGLstream's post_damage() would unconditionally return success
|
||||
regardless of the actual status of the eglSwapBuffers().
|
||||
|
||||
Yet, if eglSwapBuffers() fails, we should not post the corresponding
|
||||
damage as they wouldn't match the actual content of the buffer.
|
||||
|
||||
Use the eglSwapBuffers() return value as the return value for
|
||||
post_damage() and do not take a refrence on the pixmap if it fails.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
(cherry picked from commit b583395cd38ad101c7541bd8b0e91143ced44703)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 14 ++++++++++----
|
||||
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 3a3caa976..6721acfe8 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -750,14 +750,20 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
if (xwl_eglstream->have_egl_damage)
|
||||
- eglSwapBuffersWithDamageKHR(xwl_screen->egl_display,
|
||||
- xwl_pixmap->surface, egl_damage, 1);
|
||||
+ status = eglSwapBuffersWithDamageKHR(xwl_screen->egl_display,
|
||||
+ xwl_pixmap->surface,
|
||||
+ egl_damage, 1);
|
||||
else
|
||||
- eglSwapBuffers(xwl_screen->egl_display, xwl_pixmap->surface);
|
||||
+ status = eglSwapBuffers(xwl_screen->egl_display,
|
||||
+ xwl_pixmap->surface);
|
||||
+
|
||||
+ if (!status) {
|
||||
+ ErrorF("eglstream: buffer swap failed, not posting damage\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
/* hang onto the pixmap until the compositor has released it */
|
||||
pixmap->refcnt++;
|
||||
- status = TRUE;
|
||||
|
||||
out:
|
||||
/* Restore previous state */
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
From 7b06e468b37164eeaa18fc32cba801de0eee4eb1 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Tue, 4 May 2021 10:56:38 +0200
|
||||
Subject: [PATCH xserver 19/27] xwayland/eglstream: Do not always increment
|
||||
pixmap refcnt on commit
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Currently, the EGLstream backend would increment the pixmap refcount for
|
||||
each commit, and decrease that refcount on the wl_buffer release
|
||||
callback.
|
||||
|
||||
But that's relying on the compositor sending us a release callback for
|
||||
each commit, otherwise the pixmap refcount will keep increasing and the
|
||||
pixmap will be leaked.
|
||||
|
||||
So instead, increment the refcount on the pixmap only when we have not
|
||||
received a release notification for the wl_buffer, to avoid increasing
|
||||
the pixmap refcount more than once without a corresponding release
|
||||
event.
|
||||
|
||||
This way, if the pixmap is still in use when released on the X11 side,
|
||||
the EGL stream will be kept until the compositor releases it.
|
||||
|
||||
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 d85bfa6ab7495281516f3a4b05dc1ff0b2c4bf91)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 21 +++++++++++++++++----
|
||||
1 file changed, 17 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 6721acfe8..64f4e31f5 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -89,6 +89,7 @@ struct xwl_pixmap {
|
||||
struct xwl_screen *xwl_screen;
|
||||
struct wl_buffer *buffer;
|
||||
struct xwl_eglstream_pending_stream *pending_stream;
|
||||
+ Bool wait_for_buffer_release;
|
||||
|
||||
/* XWL_PIXMAP_EGLSTREAM. */
|
||||
EGLStreamKHR stream;
|
||||
@@ -577,8 +578,16 @@ xwl_eglstream_queue_pending_stream(WindowPtr window, PixmapPtr pixmap)
|
||||
static void
|
||||
xwl_eglstream_buffer_release_callback(void *data)
|
||||
{
|
||||
- /* drop the reference we took in post_damage, freeing if necessary */
|
||||
- dixDestroyPixmap(data, 0);
|
||||
+ PixmapPtr pixmap = data;
|
||||
+ struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
|
||||
+
|
||||
+ assert(xwl_pixmap);
|
||||
+
|
||||
+ if (xwl_pixmap->wait_for_buffer_release) {
|
||||
+ xwl_pixmap->wait_for_buffer_release = FALSE;
|
||||
+ /* drop the reference we took in the ready callback, freeing if necessary */
|
||||
+ dixDestroyPixmap(pixmap, 0);
|
||||
+ }
|
||||
}
|
||||
|
||||
static const struct wl_buffer_listener xwl_eglstream_buffer_release_listener = {
|
||||
@@ -606,6 +615,7 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
|
||||
|
||||
xwl_glamor_egl_make_current(xwl_screen);
|
||||
|
||||
+ xwl_pixmap->wait_for_buffer_release = FALSE;
|
||||
xwl_pixmap->xwl_screen = xwl_screen;
|
||||
xwl_pixmap->surface = EGL_NO_SURFACE;
|
||||
xwl_pixmap->stream = eglCreateStreamKHR(xwl_screen->egl_display, NULL);
|
||||
@@ -762,8 +772,11 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /* hang onto the pixmap until the compositor has released it */
|
||||
- pixmap->refcnt++;
|
||||
+ if (!xwl_pixmap->wait_for_buffer_release) {
|
||||
+ /* hang onto the pixmap until the compositor has released it */
|
||||
+ pixmap->refcnt++;
|
||||
+ xwl_pixmap->wait_for_buffer_release = TRUE;
|
||||
+ }
|
||||
|
||||
out:
|
||||
/* Restore previous state */
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
From 9519ebe96344ec64e8f18eae2420df101c446a1a Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Fri, 30 Apr 2021 16:23:10 +0200
|
||||
Subject: [PATCH xserver 20/27] xwayland/eglstream: Set ALU to GXCopy for
|
||||
blitting
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The EGLstream backend's post damage function uses a shader and
|
||||
glDrawArrays() to copy the data from the glamor's pixmap texture prior
|
||||
to do the eglSwapBuffers().
|
||||
|
||||
However, glDrawArrays() can be affected by the GL state, and therefore
|
||||
not reliably produce the expected copy, causing the content of the
|
||||
buffer to be corrupted.
|
||||
|
||||
Make sure to set the ALU to GXCopy prior to call glDrawArrays() to get
|
||||
the expected result.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Suggested-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
(cherry picked from commit 012350e3db47fef0404346f55968032e62004fcf)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 64f4e31f5..2094d293a 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -33,6 +33,7 @@
|
||||
#define EGL_NO_X11
|
||||
#include <glamor_egl.h>
|
||||
#include <glamor.h>
|
||||
+#include <glamor_priv.h>
|
||||
#include <glamor_transform.h>
|
||||
#include <glamor_transfer.h>
|
||||
|
||||
@@ -727,6 +728,8 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
|
||||
* won't actually draw to it
|
||||
*/
|
||||
xwl_glamor_egl_make_current(xwl_screen);
|
||||
+ glamor_set_alu(xwl_screen->screen, GXcopy);
|
||||
+
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
if (eglGetCurrentSurface(EGL_READ) != xwl_pixmap->surface ||
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
From 64deb9471c7d9cad4c2ec1de1fba6a35c9af8e68 Mon Sep 17 00:00:00 2001
|
||||
From: Erik Kurzinger <ekurzinger@nvidia.com>
|
||||
Date: Fri, 14 May 2021 08:26:49 -0400
|
||||
Subject: [PATCH xserver 21/27] xwayland/eglstream: allow commits to dma-buf
|
||||
backed pixmaps
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
As of commit 098e0f52 xwl_glamor_eglstream_allow_commits will not allow commits
|
||||
if the xwl_pixmap does not have an EGLSurface. This is valid for pixmaps backed
|
||||
by an EGLStream, however pixmaps backed by a dma-buf for OpenGL or Vulkan
|
||||
rendering will never have an EGLSurface. Unlike EGLStream backed pixmaps,
|
||||
though, glamor will render directly to the buffer that Xwayland passes to the
|
||||
compositor. Hence, they don't require the intermediate copy in
|
||||
xwl_glamor_eglstream_post_damage that EGLStream backed pixmaps do, so there is
|
||||
no need for an EGLSurface.
|
||||
|
||||
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
|
||||
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
(cherry picked from commit 3d33d885fcd1215a74c1819278cf6f9557c9860b)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 2094d293a..2d0827709 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -681,7 +681,8 @@ xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
|
||||
|
||||
return FALSE;
|
||||
} else {
|
||||
- if (xwl_pixmap->surface != EGL_NO_SURFACE)
|
||||
+ 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
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
From 29cba30948cda34e744314343109964ff9ed515c Mon Sep 17 00:00:00 2001
|
||||
From: Erik Kurzinger <ekurzinger@nvidia.com>
|
||||
Date: Tue, 11 May 2021 17:00:21 -0400
|
||||
Subject: [PATCH xserver 22/27] xwayland/eglstream: flush stream after
|
||||
eglSwapBuffers
|
||||
|
||||
When eglSwapBuffers inserts a new frame into a window's stream, there may be a
|
||||
delay before the state of the consumer end of the stream is updated to reflect
|
||||
this. If the subsequent wl_surface_attach, wl_surface_damage, wl_surface_commit
|
||||
calls are received by the compositor before then, it will (typically) re-use
|
||||
the previous frame acquired from the stream instead of the latest one.
|
||||
|
||||
This can leave the window displaying out-of-date contents, which might never be
|
||||
updated thereafter.
|
||||
|
||||
To fix this, after calling eglSwapBuffers, xwl_glamor_eglstream_post_damage
|
||||
should call eglStreamFlushNV. This call will block until it can be guaranteed
|
||||
that the state of the consumer end of the stream has been updated to reflect
|
||||
that a new frame is available.
|
||||
|
||||
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1171
|
||||
|
||||
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
|
||||
(cherry picked from commit 7515c23a416825f0db51f9b445279b12d5918ebf)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 2d0827709..c583a1390 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -72,6 +72,7 @@ struct xwl_eglstream_private {
|
||||
SetWindowPixmapProcPtr SetWindowPixmap;
|
||||
|
||||
Bool have_egl_damage;
|
||||
+ Bool have_egl_stream_flush;
|
||||
|
||||
GLint blit_prog;
|
||||
GLuint blit_vao;
|
||||
@@ -776,6 +777,13 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
|
||||
goto out;
|
||||
}
|
||||
|
||||
+#ifdef EGL_NV_stream_flush
|
||||
+ if (xwl_eglstream->have_egl_stream_flush)
|
||||
+ /* block until stream state is updated on the compositor's side */
|
||||
+ eglStreamFlushNV(xwl_screen->egl_display,
|
||||
+ xwl_pixmap->stream);
|
||||
+#endif
|
||||
+
|
||||
if (!xwl_pixmap->wait_for_buffer_release) {
|
||||
/* hang onto the pixmap until the compositor has released it */
|
||||
pixmap->refcnt++;
|
||||
@@ -1173,6 +1181,18 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
|
||||
ErrorF("Driver lacks EGL_KHR_swap_buffers_with_damage, performance "
|
||||
"will be affected\n");
|
||||
|
||||
+#ifdef EGL_NV_stream_flush
|
||||
+ xwl_eglstream->have_egl_stream_flush =
|
||||
+ epoxy_has_egl_extension(xwl_screen->egl_display,
|
||||
+ "EGL_NV_stream_flush");
|
||||
+#else
|
||||
+ xwl_eglstream->have_egl_stream_flush = FALSE;
|
||||
+#endif /* EGL_NV_stream_flush */
|
||||
+
|
||||
+ if (!xwl_eglstream->have_egl_stream_flush)
|
||||
+ ErrorF("EGL_NV_stream_flush not available, "
|
||||
+ "this may cause visible corruption.\n");
|
||||
+
|
||||
xwl_eglstream_init_shaders(xwl_screen);
|
||||
|
||||
if (epoxy_has_gl_extension("GL_OES_EGL_image") &&
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
From 4c01758cbe7db02d84ac0cba0c626e855bf927d6 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Thu, 20 May 2021 12:11:42 +0200
|
||||
Subject: [PATCH xserver 23/27] xwayland: Add preferred GLVND vendor to
|
||||
xwl_screen
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If Xwayland's EGLstream backend supports hardware acceleration with the
|
||||
NVIDIA closed-source driver, the GLX library also needs to be one
|
||||
shipped by NVIDIA, that's what GLVND is for.
|
||||
|
||||
Add a new member to the xwl_screen that the backend can optionally set
|
||||
to the preferred GLVND vendor to use.
|
||||
|
||||
If not set, "mesa" is assumed.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
(cherry picked from commit 24fc8aea1e4bbaba780f1a316fba797a0198f603)
|
||||
---
|
||||
hw/xwayland/xwayland-glx.c | 3 +++
|
||||
hw/xwayland/xwayland-screen.h | 3 +++
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glx.c b/hw/xwayland/xwayland-glx.c
|
||||
index 7e2a87fc1..eba8946ab 100644
|
||||
--- a/hw/xwayland/xwayland-glx.c
|
||||
+++ b/hw/xwayland/xwayland-glx.c
|
||||
@@ -378,6 +378,9 @@ egl_screen_probe(ScreenPtr pScreen)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ if (!screen->base.glvnd && xwl_screen->glvnd_vendor)
|
||||
+ screen->base.glvnd = strdup(xwl_screen->glvnd_vendor);
|
||||
+
|
||||
if (!screen->base.glvnd)
|
||||
screen->base.glvnd = strdup("mesa");
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
|
||||
index 5fe4712bd..b965dddd7 100644
|
||||
--- a/hw/xwayland/xwayland-screen.h
|
||||
+++ b/hw/xwayland/xwayland-screen.h
|
||||
@@ -107,6 +107,9 @@ struct xwl_screen {
|
||||
struct glamor_context *glamor_ctx;
|
||||
|
||||
Atom allow_commits_prop;
|
||||
+
|
||||
+ /* The preferred GLVND vendor. If NULL, "mesa" is assumed. */
|
||||
+ const char *glvnd_vendor;
|
||||
};
|
||||
|
||||
/* Apps which use randr/vidmode to change the mode when going fullscreen,
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
From 430eb872784c04e825126e0d7454f3a5bbefff70 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Mon, 17 May 2021 18:20:57 +0200
|
||||
Subject: [PATCH xserver 24/27] xwayland/eglstream: Use "nvidia" for GLVND
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If the EGLStream backend is able to use hardware acceleration with the
|
||||
NVIDIA closed source driver, we should use the "nvidia" GLX
|
||||
implementation instead of the one from Mesa to take advantage of the
|
||||
NVIDIA hardware accelerated rendering.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
(cherry picked from commit fae58e9b03696a3890f9c876306c68ffa6f9ff30)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index c583a1390..5e89849ff 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -1195,9 +1195,11 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
|
||||
|
||||
xwl_eglstream_init_shaders(xwl_screen);
|
||||
|
||||
- if (epoxy_has_gl_extension("GL_OES_EGL_image") &&
|
||||
- !dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) {
|
||||
- ErrorF("DRI3 initialization failed. Performance will be affected.\n");
|
||||
+ if (epoxy_has_gl_extension("GL_OES_EGL_image")) {
|
||||
+ if (dri3_screen_init(xwl_screen->screen, &xwl_dri3_info))
|
||||
+ xwl_screen->glvnd_vendor = "nvidia";
|
||||
+ else
|
||||
+ ErrorF("DRI3 initialization failed. Performance will be affected.\n");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
From 0cb42b7de629e74afed9b19d47672cebfe08f12e Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Thu, 20 May 2021 16:46:33 +0200
|
||||
Subject: [PATCH xserver 25/27] xwayland/eglstream: Log when GL_OES_EGL_image
|
||||
is missing
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
That will dramatically affect performance, might as well log when we
|
||||
cannot use GL_OES_EGL_image with the NVIDIA closed-source driver.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||||
(cherry picked from commit 34a58d7714025bc1043bf5282358406eb10e4b8e)
|
||||
---
|
||||
hw/xwayland/xwayland-glamor-eglstream.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
index 5e89849ff..0affc954c 100644
|
||||
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||||
@@ -1200,6 +1200,8 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
|
||||
xwl_screen->glvnd_vendor = "nvidia";
|
||||
else
|
||||
ErrorF("DRI3 initialization failed. Performance will be affected.\n");
|
||||
+ } else {
|
||||
+ ErrorF("Driver lacks GL_OES_EGL_image, performance will be affected.\n");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
From a604a0a26791e9f352aad27232127d729bca4334 Mon Sep 17 00:00:00 2001
|
||||
From: Erik Kurzinger <ekurzinger@nvidia.com>
|
||||
Date: Thu, 10 Dec 2020 14:24:32 -0800
|
||||
Subject: [PATCH xserver 26/27] glx: don't create implicit GLXWindow if one
|
||||
already exists
|
||||
|
||||
If a GLXMakeCurrent request specifies an X window as its drawable,
|
||||
__glXGetDrawable will implicitly create a GLXWindow for it. However,
|
||||
the client may have already explicitly created a GLXWindow for that X
|
||||
window. If that happens, two __glXDrawableRes resources will be added
|
||||
to the window.
|
||||
|
||||
If the explicitly-created GLXWindow is later destroyed by the client,
|
||||
DrawableGone will call FreeResourceByType on the X window, but this
|
||||
will actually free the resource for the implicitly-created GLXWindow,
|
||||
since that one would be at the head of the list.
|
||||
|
||||
Then if the X window is destroyed after that, the resource for the
|
||||
explicitly-created GLXWindow will be freed. But that GLXWindow was
|
||||
already destroyed above. This crashes the server when it tries to call
|
||||
the destroyed GLXWindow's destructor. It also means the
|
||||
implicitly-created GLXWindow would have been leaked since the
|
||||
FreeResourceByType call mentioned above skips calling the destructor.
|
||||
|
||||
To fix this, if __glXGetDrawable is given an X window, it should check
|
||||
if there is already a GLXWindow associated with it, and only create an
|
||||
implicit one if there is not.
|
||||
|
||||
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
|
||||
Reviewed-by: Adam Jackson <ajax@redhat.com>
|
||||
(cherry picked from commit b7a85e44da91d1663d5b4eabac06327c92a80f91)
|
||||
---
|
||||
glx/glxcmds.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
|
||||
index 37576b6ef..1b9ad6d14 100644
|
||||
--- a/glx/glxcmds.c
|
||||
+++ b/glx/glxcmds.c
|
||||
@@ -487,8 +487,15 @@ __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
|
||||
__GLXscreen *pGlxScreen;
|
||||
int rc;
|
||||
|
||||
- if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
|
||||
- DixWriteAccess, &pGlxDraw, &rc)) {
|
||||
+ rc = dixLookupResourceByType((void **)&pGlxDraw, drawId,
|
||||
+ __glXDrawableRes, client, DixWriteAccess);
|
||||
+ if (rc == Success &&
|
||||
+ /* If pGlxDraw->drawId == drawId, drawId is a valid GLX drawable.
|
||||
+ * Otherwise, if pGlxDraw->type == GLX_DRAWABLE_WINDOW, drawId is
|
||||
+ * an X window, but the client has already created a GLXWindow
|
||||
+ * associated with it, so we don't want to create another one. */
|
||||
+ (pGlxDraw->drawId == drawId ||
|
||||
+ pGlxDraw->type == GLX_DRAWABLE_WINDOW)) {
|
||||
if (glxc != NULL &&
|
||||
glxc->config != NULL &&
|
||||
glxc->config != pGlxDraw->config) {
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
From 1607ac6870f7cf67c30b96529ea5ca389c771a3d Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Thu, 3 Jun 2021 17:51:01 +0200
|
||||
Subject: [PATCH xserver 27/27] glx: Set ContextTag for all contexts
|
||||
|
||||
Currently, xorgGlxMakeCurrent() would set the context tag only for
|
||||
indirect GLX contexts.
|
||||
|
||||
However, several other places expect to find a context for the tag or
|
||||
they would raise a GLXBadContextTag error, such as WaitGL() or WaitX().
|
||||
|
||||
Set the context tag for direct contexts as well, to avoid raising an
|
||||
error and possibly killing the client and set currentClient.
|
||||
|
||||
Thanks to Erik Kurzinger <ekurzinger@nvidia.com> for spotting the issue.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Adam Jackson <ajax@redhat.com>
|
||||
(cherry picked from commit c468d34c7208c9041f9c077b54a00ae9cccad6a3)
|
||||
(cherry picked from commit aad61e8e03311eb8bae4f7db59e65634733eadc2)
|
||||
---
|
||||
glx/glxcmds.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
|
||||
index 1b9ad6d14..8b2170306 100644
|
||||
--- a/glx/glxcmds.c
|
||||
+++ b/glx/glxcmds.c
|
||||
@@ -662,10 +662,11 @@ xorgGlxMakeCurrent(ClientPtr client, GLXContextTag tag, XID drawId, XID readId,
|
||||
glxc->readPriv = NULL;
|
||||
return __glXError(GLXBadContext);
|
||||
}
|
||||
+ }
|
||||
|
||||
+ glxServer.setContextTagPrivate(client, newContextTag, glxc);
|
||||
+ if (glxc)
|
||||
glxc->currentClient = client;
|
||||
- glxServer.setContextTagPrivate(client, newContextTag, glxc);
|
||||
- }
|
||||
|
||||
if (prevglxc) {
|
||||
prevglxc->currentClient = NULL;
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
Summary: Xwayland
|
||||
Name: xorg-x11-server-Xwayland
|
||||
Version: 21.1.1
|
||||
Release: 6%{?gitdate:.%{gitdate}git%{shortcommit}}%{?dist}
|
||||
Version: 21.1.3
|
||||
Release: 15%{?gitdate:.%{gitdate}git%{shortcommit}}%{?dist}
|
||||
|
||||
URL: http://www.x.org
|
||||
%if 0%{?gitdate}
|
||||
|
@ -18,36 +18,69 @@ Source0: https://gitlab.freedesktop.org/xorg/%{pkgname}/-/archive/%{commit}/%{
|
|||
Source0: https://www.x.org/pub/individual/xserver/%{pkgname}-%{version}.tar.xz
|
||||
%endif
|
||||
|
||||
Patch1: 0001-xwayland-Move-dmabuf-interface-to-common-glamor-code.patch
|
||||
Patch2: 0002-xwayland-move-formats-and-modifiers-functions-to-com.patch
|
||||
Patch3: 0003-xwayland-Add-check_flip-glamor-backend-function.patch
|
||||
Patch4: 0004-xwayland-implement-pixmap_from_buffers-for-the-eglst.patch
|
||||
Patch5: 0005-xwayland-eglstream-fix-X11-rendering-to-flipping-GL-.patch
|
||||
Patch6: 0006-xwayland-eglstream-Check-buffer-creation.patch
|
||||
Patch7: 0007-xwayland-Check-buffer-prior-to-attaching-it.patch
|
||||
Patch8: 0008-glamor-Dump-backtrace-on-GL-error.patch
|
||||
Patch9: 0009-xwayland-glamor-Add-return-status-to-post_damage.patch
|
||||
Patch10: 0010-xwayland-eglstream-Check-framebuffer-status.patch
|
||||
Patch11: 0011-xwayland-eglstream-Small-refactoring.patch
|
||||
Patch12: 0012-xwayland-eglstream-Add-more-error-checking.patch
|
||||
Patch13: 0013-xwayland-eglstream-Dissociate-pending-stream-from-wi.patch
|
||||
Patch14: 0014-xwayland-eglstream-Keep-a-reference-to-the-pixmap.patch
|
||||
Patch15: 0015-xwayland-eglstream-Drop-the-list-of-pending-streams.patch
|
||||
Patch16: 0016-xwayland-eglstream-Do-not-commit-without-surface.patch
|
||||
Patch17: 0017-xwayland-eglstream-Fix-calloc-malloc.patch
|
||||
Patch18: 0018-xwayland-eglstream-Check-eglSwapBuffers.patch
|
||||
Patch19: 0019-xwayland-eglstream-Do-not-always-increment-pixmap-re.patch
|
||||
Patch20: 0020-xwayland-eglstream-Set-ALU-to-GXCopy-for-blitting.patch
|
||||
Patch21: 0021-xwayland-eglstream-allow-commits-to-dma-buf-backed-p.patch
|
||||
Patch22: 0022-xwayland-eglstream-flush-stream-after-eglSwapBuffers.patch
|
||||
Patch23: 0023-xwayland-Add-preferred-GLVND-vendor-to-xwl_screen.patch
|
||||
Patch24: 0024-xwayland-eglstream-Use-nvidia-for-GLVND.patch
|
||||
Patch25: 0025-xwayland-eglstream-Log-when-GL_OES_EGL_image-is-miss.patch
|
||||
Patch26: 0026-glx-don-t-create-implicit-GLXWindow-if-one-already-e.patch
|
||||
Patch27: 0027-glx-Set-ContextTag-for-all-contexts.patch
|
||||
# https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/704
|
||||
Patch28: 0001-xwayland-eglstream-Keep-pending-stream-if-the-pixmap.patch
|
||||
Patch29: 0002-xwayland-eglstream-Remove-stream-validity.patch
|
||||
Patch1: 0001-xwayland-eglstream-Demote-EGLstream-device-warning.patch
|
||||
Patch2: 0002-xwayland-glamor-Change-errors-to-verbose-messages.patch
|
||||
Patch3: 0003-xwayland-glamor-Log-backend-selected-for-debug.patch
|
||||
Patch4: 0004-xwayland-eglstream-Prefer-EGLstream-if-available.patch
|
||||
Patch5: 0001-present-Send-a-PresentConfigureNotify-event-for-dest.patch
|
||||
|
||||
# CVE-2021-4011
|
||||
Patch10001: 0001-record-Fix-out-of-bounds-access-in-SwapCreateRegiste.patch
|
||||
# CVE-2021-4009
|
||||
Patch10002: 0002-xfixes-Fix-out-of-bounds-access-in-ProcXFixesCreateP.patch
|
||||
# CVE-2021-4010
|
||||
Patch10003: 0003-Xext-Fix-out-of-bounds-access-in-SProcScreenSaverSus.patch
|
||||
# CVE-2021-4008
|
||||
Patch10004: 0004-render-Fix-out-of-bounds-access-in-SProcRenderCompos.patch
|
||||
# CVE-2022-2319/ZDI-CAN-16062, CVE-2022-2320/ZDI-CAN-16070
|
||||
Patch10005: 0001-xkb-switch-to-array-index-loops-to-moving-pointers.patch
|
||||
Patch10006: 0002-xkb-swap-XkbSetDeviceInfo-and-XkbSetDeviceInfoCheck.patch
|
||||
Patch10007: 0003-xkb-add-request-length-validation-for-XkbSetGeometry.patch
|
||||
# CVE-2022-3550
|
||||
Patch10008: 0001-xkb-proof-GetCountedString-against-request-length-at.patch
|
||||
# CVE-2022-3551
|
||||
Patch10009: 0001-xkb-fix-some-possible-memleaks-in-XkbGetKbdByName.patch
|
||||
# CVE-2022-46340
|
||||
Patch10018: 0001-Xtest-disallow-GenericEvents-in-XTestSwapFakeInput.patch
|
||||
# related to CVE-2022-46344
|
||||
Patch10019: 0002-Xi-return-an-error-from-XI-property-changes-if-verif.patch
|
||||
# CVE-2022-46344
|
||||
Patch10020: 0003-Xi-avoid-integer-truncation-in-length-check-of-ProcX.patch
|
||||
# CVE-2022-46341
|
||||
Patch10021: 0004-Xi-disallow-passive-grabs-with-a-detail-255.patch
|
||||
# CVE-2022-46343
|
||||
Patch10022: 0005-Xext-free-the-screen-saver-resource-when-replacing-i.patch
|
||||
# CVE-2022-46342
|
||||
Patch10023: 0006-Xext-free-the-XvRTVideoNotify-when-turning-off-from-.patch
|
||||
# CVE-2022-4283
|
||||
Patch10024: 0007-xkb-reset-the-radio_groups-pointer-to-NULL-after-fre.patch
|
||||
# Follow-up to CVE-2022-46340
|
||||
Patch10025: 0008-Xext-fix-invalid-event-type-mask-in-XTestSwapFakeInp.patch
|
||||
# CVE-2023-0494
|
||||
Patch10026: 0001-Xi-fix-potential-use-after-free-in-DeepCopyPointerCl.patch
|
||||
# CVE-2023-1393
|
||||
Patch10027: 0001-composite-Fix-use-after-free-of-the-COW.patch
|
||||
# CVE-2023-5367
|
||||
Patch10028: 0001-Xi-randr-fix-handling-of-PropModeAppend-Prepend.patch
|
||||
# CVE-2023-6478
|
||||
Patch10029: 0001-randr-avoid-integer-truncation-in-length-check-of-Pr.patch
|
||||
# CVE-2023-6377
|
||||
Patch10030: 0001-Xi-allocate-enough-XkbActions-for-our-buttons.patch
|
||||
# Fix for CVE-2023-6816, ZDI-CAN-22664, ZDI-CAN-22665
|
||||
Patch10031: 0001-dix-allocate-enough-space-for-logical-button-maps.patch
|
||||
# Fix for CVE-2024-0229, ZDI-CAN-22678
|
||||
Patch10032: 0002-dix-Allocate-sufficient-xEvents-for-our-DeviceStateN.patch
|
||||
Patch10033: 0003-dix-fix-DeviceStateNotify-event-calculation.patch
|
||||
Patch10034: 0004-Xi-when-creating-a-new-ButtonClass-set-the-number-of.patch
|
||||
# Fix for CVE-2024-21885, ZDI-CAN-22744
|
||||
Patch10035: 0005-Xi-flush-hierarchy-events-after-adding-removing-mast.patch
|
||||
# Fix for CVE-2024-21886, ZDI-CAN-22840
|
||||
Patch10036: 0006-Xi-do-not-keep-linked-list-pointer-during-recursion.patch
|
||||
Patch10037: 0007-dix-when-disabling-a-master-float-disabled-slaved-de.patch
|
||||
# Fix for CVE-2024-0408
|
||||
Patch10038: 0008-glx-Call-XACE-hooks-on-the-GLX-buffer.patch
|
||||
# Fix for CVE-2024-0409
|
||||
Patch10039: 0009-ephyr-xwayland-Use-the-proper-private-key-for-cursor.patch
|
||||
|
||||
License: MIT
|
||||
|
||||
|
@ -155,6 +188,58 @@ rm -Rf $RPM_BUILD_ROOT%{_localstatedir}/lib/xkb
|
|||
%{_libdir}/pkgconfig/xwayland.pc
|
||||
|
||||
%changelog
|
||||
* Tue Jan 16 2024 Olivier Fourdan <ofourdan@redhat.com> - 21.1.3-15
|
||||
Fix for CVE-2023-6816, CVE-2024-0229, CVE-2024-21885, CVE-2024-21886,
|
||||
CVE-2024-0408, CVE-2024-0409
|
||||
|
||||
* Wed Dec 13 2023 Olivier Fourdan <ofourdan@redhat.com> - 21.1.3-14
|
||||
- Fix for CVE-2023-6377, CVE-2023-6478
|
||||
|
||||
* Wed Oct 25 2023 Olivier Fourdan <ofourdan@redhat.com> - 21.1.3-13
|
||||
- Fix for CVE-2023-5367
|
||||
|
||||
* Tue Jun 13 2023 Olivier Fourdan <ofourdan@redhat.com> - 21.1.3-12
|
||||
- Backport fix for a deadlock with DRI3
|
||||
Resolves: rhbz#2212831
|
||||
|
||||
* Fri Mar 31 2023 Olivier Fourdan <ofourdan@redhat.com> - 21.1.3-11
|
||||
- Fix CVE-2023-1393 (#2180298)
|
||||
|
||||
* Tue Feb 7 2023 Olivier Fourdan <ofourdan@redhat.com> - 21.1.3-10
|
||||
- Fix CVE-2023-0494 (#2166972)
|
||||
|
||||
* Mon Dec 19 2022 Peter Hutterer <peter.hutterer@redhat.com> - 21.1.3-9
|
||||
- Follow-up fix for CVE-2022-46340 (#2151777)
|
||||
|
||||
* Tue Dec 13 2022 Peter Hutterer <peter.hutterer@redhat.com> - 21.1.3-8
|
||||
- CVE fix for: CVE-2022-4283 (#2151802), CVE-2022-46340 (#2151777),
|
||||
CVE-2022-46341 (#2151782), CVE-2022-46342 (#2151785),
|
||||
CVE-2022-46343 (#2151792), CVE-2022-46344 (#2151795)
|
||||
|
||||
* Mon Nov 14 2022 Olivier Fourdan <ofourdan@redhat.com> - 21.1.3-7
|
||||
- Fix CVE-2022-3550, CVE-2022-3551
|
||||
Resolves: rhbz#2140767, rhbz#2140774
|
||||
|
||||
* Fri Jul 29 2022 Olivier Fourdan <ofourdan@redhat.com> - 21.1.3-6
|
||||
- CVE fix for: CVE-2022-2319/ZDI-CAN-16062, CVE-2022-2320/ZDI-CAN-16070
|
||||
Resolves: rhbz#2110442, rhbz#2110437
|
||||
|
||||
* Thu Jun 09 2022 Ray Strode <rstrode@redhat.com> - 21.1.3-5
|
||||
- Rebuild again for ipv6 xtrans fix
|
||||
Related: #2075132
|
||||
|
||||
* Tue May 24 2022 Ray Strode <rstrode@redhat.com> - 21.1.3-3
|
||||
- Rebuild for ipv6 xtrans fix
|
||||
Related: #2075132
|
||||
|
||||
* Fri Jan 7 2022 Olivier Fourdan <ofourdan@redhat.com> - 21.1.3-2
|
||||
- CVE fix for: CVE-2021-4008 (#2038066), CVE-2021-4009 (#2038068),
|
||||
CVE-2021-4010 (#2038071), CVE-2021-4011 (#2038073)
|
||||
|
||||
* Thu Dec 2 2021 Olivier Fourdan <ofourdan@redhat.com> - 21.1.3-1
|
||||
- Rebase to 21.1.3 (rhbz#2015842)
|
||||
- Prefer EGLstream if both EGLstream and GBM are usable
|
||||
|
||||
* Mon Aug 9 2021 Olivier Fourdan <ofourdan@redhat.com> - 21.1.1-6
|
||||
- Backport the latest fixes from Xwayland for EGLstream (rhbz#1977741)
|
||||
|
||||
|
|
Loading…
Reference in New Issue