From 1530c7de53c369e50c7463cf4f31c47755bdaed5 Mon Sep 17 00:00:00 2001 From: stefan11111 Date: Wed, 25 Mar 2026 23:10:51 +0200 Subject: [PATCH] glxmor/glamor_egl: Move `glamor_egl_close_screen` to the post screen close hook We want drivers' close screen hooks to be called before glamor's close screen hook, because they may have gbm bo's created with glamor's gbm device. If we free the gbm device before the driver frees all gbm bo's, then the drivers could have an use-after-free when freeing the bo's. This fixes a memory leak, since before this change, we were just leaking everything glamor mapped to a screen, not freeing EGLImages, gbm devices, etc. Signed-off-by: stefan11111 --- dix/screen_hooks_priv.h | 6 ++++++ glamor/glamor_egl.c | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/dix/screen_hooks_priv.h b/dix/screen_hooks_priv.h index 3ab6bfdda..c4880d858 100644 --- a/dix/screen_hooks_priv.h +++ b/dix/screen_hooks_priv.h @@ -157,7 +157,10 @@ void dixScreenUnhookClose(ScreenPtr pScreen, * proc had been called. * * When registration fails, the server aborts. + * + * NOTE: only exported for libglamoregl, not supposed to be used by drivers. **/ +_X_EXPORT void dixScreenHookPostClose(ScreenPtr pScreen, XorgScreenCloseProcPtr func); @@ -174,7 +177,10 @@ void dixScreenHookPostClose(ScreenPtr pScreen, * * In contrast to Close hook, it's called *after* the driver's CloseScreen() * proc had been called. + * + * NOTE: only exported for libglamoregl, not supposed to be used by drivers. **/ +_X_EXPORT void dixScreenUnhookPostClose(ScreenPtr pScreen, XorgScreenCloseProcPtr func); diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index d27932ba2..f7d7da47f 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -976,7 +976,9 @@ static void glamor_egl_close_screen(CallbackListPtr *pcbl, ScreenPtr screen, voi eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image); pixmap_priv->image = NULL; - dixScreenUnhookClose(screen, glamor_egl_close_screen); + glamor_egl_cleanup(glamor_egl); + + dixScreenUnhookPostClose(screen, glamor_egl_close_screen); dixScreenUnhookPixmapDestroy(screen, glamor_egl_pixmap_destroy); } @@ -1055,7 +1057,7 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx) #endif const char *gbm_backend_name; - dixScreenHookClose(screen, glamor_egl_close_screen); + dixScreenHookPostClose(screen, glamor_egl_close_screen); dixScreenHookPixmapDestroy(screen, glamor_egl_pixmap_destroy); glamor_ctx->ctx = glamor_egl->context;