summaryrefslogtreecommitdiff
path: root/glx
diff options
context:
space:
mode:
authorErik Kurzinger <ekurzinger@nvidia.com>2020-12-10 14:24:32 -0800
committerOlivier Fourdan <fourdan@gmail.com>2021-06-07 14:53:13 +0000
commitb7a85e44da91d1663d5b4eabac06327c92a80f91 (patch)
treef20a067e0ab0643795dbb235a6fdf94ddd15ce3a /glx
parent8274dd664335cd72739a1107f174e7a974a9ea24 (diff)
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>
Diffstat (limited to 'glx')
-rw-r--r--glx/glxcmds.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 368d66aa6..2f69c794a 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) {