|
|
5f5628 |
From a604a0a26791e9f352aad27232127d729bca4334 Mon Sep 17 00:00:00 2001
|
|
|
5f5628 |
From: Erik Kurzinger <ekurzinger@nvidia.com>
|
|
|
5f5628 |
Date: Thu, 10 Dec 2020 14:24:32 -0800
|
|
|
5f5628 |
Subject: [PATCH xserver 26/27] glx: don't create implicit GLXWindow if one
|
|
|
5f5628 |
already exists
|
|
|
5f5628 |
|
|
|
5f5628 |
If a GLXMakeCurrent request specifies an X window as its drawable,
|
|
|
5f5628 |
__glXGetDrawable will implicitly create a GLXWindow for it. However,
|
|
|
5f5628 |
the client may have already explicitly created a GLXWindow for that X
|
|
|
5f5628 |
window. If that happens, two __glXDrawableRes resources will be added
|
|
|
5f5628 |
to the window.
|
|
|
5f5628 |
|
|
|
5f5628 |
If the explicitly-created GLXWindow is later destroyed by the client,
|
|
|
5f5628 |
DrawableGone will call FreeResourceByType on the X window, but this
|
|
|
5f5628 |
will actually free the resource for the implicitly-created GLXWindow,
|
|
|
5f5628 |
since that one would be at the head of the list.
|
|
|
5f5628 |
|
|
|
5f5628 |
Then if the X window is destroyed after that, the resource for the
|
|
|
5f5628 |
explicitly-created GLXWindow will be freed. But that GLXWindow was
|
|
|
5f5628 |
already destroyed above. This crashes the server when it tries to call
|
|
|
5f5628 |
the destroyed GLXWindow's destructor. It also means the
|
|
|
5f5628 |
implicitly-created GLXWindow would have been leaked since the
|
|
|
5f5628 |
FreeResourceByType call mentioned above skips calling the destructor.
|
|
|
5f5628 |
|
|
|
5f5628 |
To fix this, if __glXGetDrawable is given an X window, it should check
|
|
|
5f5628 |
if there is already a GLXWindow associated with it, and only create an
|
|
|
5f5628 |
implicit one if there is not.
|
|
|
5f5628 |
|
|
|
5f5628 |
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
|
|
|
5f5628 |
Reviewed-by: Adam Jackson <ajax@redhat.com>
|
|
|
5f5628 |
(cherry picked from commit b7a85e44da91d1663d5b4eabac06327c92a80f91)
|
|
|
5f5628 |
---
|
|
|
5f5628 |
glx/glxcmds.c | 11 +++++++++--
|
|
|
5f5628 |
1 file changed, 9 insertions(+), 2 deletions(-)
|
|
|
5f5628 |
|
|
|
5f5628 |
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
|
|
|
5f5628 |
index 37576b6ef..1b9ad6d14 100644
|
|
|
5f5628 |
--- a/glx/glxcmds.c
|
|
|
5f5628 |
+++ b/glx/glxcmds.c
|
|
|
5f5628 |
@@ -487,8 +487,15 @@ __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
|
|
|
5f5628 |
__GLXscreen *pGlxScreen;
|
|
|
5f5628 |
int rc;
|
|
|
5f5628 |
|
|
|
5f5628 |
- if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
|
|
|
5f5628 |
- DixWriteAccess, &pGlxDraw, &rc)) {
|
|
|
5f5628 |
+ rc = dixLookupResourceByType((void **)&pGlxDraw, drawId,
|
|
|
5f5628 |
+ __glXDrawableRes, client, DixWriteAccess);
|
|
|
5f5628 |
+ if (rc == Success &&
|
|
|
5f5628 |
+ /* If pGlxDraw->drawId == drawId, drawId is a valid GLX drawable.
|
|
|
5f5628 |
+ * Otherwise, if pGlxDraw->type == GLX_DRAWABLE_WINDOW, drawId is
|
|
|
5f5628 |
+ * an X window, but the client has already created a GLXWindow
|
|
|
5f5628 |
+ * associated with it, so we don't want to create another one. */
|
|
|
5f5628 |
+ (pGlxDraw->drawId == drawId ||
|
|
|
5f5628 |
+ pGlxDraw->type == GLX_DRAWABLE_WINDOW)) {
|
|
|
5f5628 |
if (glxc != NULL &&
|
|
|
5f5628 |
glxc->config != NULL &&
|
|
|
5f5628 |
glxc->config != pGlxDraw->config) {
|
|
|
5f5628 |
--
|
|
|
5f5628 |
2.31.1
|
|
|
5f5628 |
|