GLX: Fix a use after free error with the GLVND vendor handle.
The GLVND layer will destroy all of the vendor handles at the end of each server generation, but the GLX module then tries to re-use the same (now-freed) handle in xorgGlxServerInit at the start of the next generation. In xorgGlxCloseExtension, explicitly destroy the vendor handle and set it to NULL so that the next call to xorgGlxServerInit will recreate it. Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
		
				
					committed by
					
						
						Adam Jackson
					
				
			
			
				
	
			
			
			
						parent
						
							31c1489eeb
						
					
				
				
					commit
					e0a137ce5d
				
			
							
								
								
									
										13
									
								
								glx/glxext.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								glx/glxext.c
									
									
									
									
									
								
							@@ -56,6 +56,7 @@ RESTYPE __glXContextRes;
 | 
			
		||||
RESTYPE __glXDrawableRes;
 | 
			
		||||
 | 
			
		||||
static DevPrivateKeyRec glxClientPrivateKeyRec;
 | 
			
		||||
static GlxServerVendor *glvnd_vendor = NULL;
 | 
			
		||||
 | 
			
		||||
#define glxClientPrivateKey (&glxClientPrivateKeyRec)
 | 
			
		||||
 | 
			
		||||
@@ -317,6 +318,10 @@ GetGLXDrawableBytes(void *value, XID id, ResourceSizePtr size)
 | 
			
		||||
static void
 | 
			
		||||
xorgGlxCloseExtension(const ExtensionEntry *extEntry)
 | 
			
		||||
{
 | 
			
		||||
    if (glvnd_vendor != NULL) {
 | 
			
		||||
        glxServer.destroyVendor(glvnd_vendor);
 | 
			
		||||
        glvnd_vendor = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    lastGLContext = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -497,11 +502,9 @@ xorgGlxServerPreInit(const ExtensionEntry *extEntry)
 | 
			
		||||
    return glxGeneration == serverGeneration;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GlxServerVendor *
 | 
			
		||||
static void
 | 
			
		||||
xorgGlxInitGLVNDVendor(void)
 | 
			
		||||
{
 | 
			
		||||
    static GlxServerVendor *glvnd_vendor = NULL;
 | 
			
		||||
 | 
			
		||||
    if (glvnd_vendor == NULL) {
 | 
			
		||||
        GlxServerImports *imports = NULL;
 | 
			
		||||
        imports = glxServer.allocateServerImports();
 | 
			
		||||
@@ -515,13 +518,11 @@ xorgGlxInitGLVNDVendor(void)
 | 
			
		||||
            glxServer.freeServerImports(imports);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return glvnd_vendor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xorgGlxServerInit(CallbackListPtr *pcbl, void *param, void *ext)
 | 
			
		||||
{
 | 
			
		||||
    GlxServerVendor *glvnd_vendor;
 | 
			
		||||
    const ExtensionEntry *extEntry = ext;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
@@ -529,7 +530,7 @@ xorgGlxServerInit(CallbackListPtr *pcbl, void *param, void *ext)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    glvnd_vendor = xorgGlxInitGLVNDVendor();
 | 
			
		||||
    xorgGlxInitGLVNDVendor();
 | 
			
		||||
    if (!glvnd_vendor) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user