Blame SOURCES/0026-glx-don-t-create-implicit-GLXWindow-if-one-already-e.patch

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