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

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