summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@qt.io>2018-04-20 12:29:16 +0200
committerDylan Baker <dylan@pnwbakers.com>2018-04-26 10:49:00 -0700
commitc862113c08539230dde214a8d874bee3a48a6019 (patch)
treeade737cf6c90cd3f41c0d88f5e6d800887db1e9b
parent56ffe03fe6e527233c98037f8f7b43289dac98a7 (diff)
st/dri: Fix dangling pointer to a destroyed dri_drawable
If an EGLSurface is created, made current and destroyed, and then a second EGLSurface is created. Then the second malloc in driCreateNewDrawable may return the same pointer address the first surface's drawable had. Consequently, when dri_make_current later tries to determine if it should update the texture_stamp it compares the surface's drawable pointer against the drawable in the last call to dri_make_current and assumes it's the same surface (which it isn't). When texture_stamp is left unset, then dri_st_framebuffer_validate thinks it has already called update_drawable_info for that drawable, leaving it unvalidated and this is when bad things starts to happen. In my case it manifested itself by the width and height of the surface being unset. This is fixed this by setting the pointer to NULL before freeing the surface. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106126 Signed-off-by: Johan Klokkhammer Helsing <johan.helsing@qt.io> Signed-off-by: Marek Olšák <marek.olsak@amd.com> Cc: 18.0 18.1 <mesa-stable@lists.freedesktop.org> (cherry picked from commit dab02dea3411d325a5aee6cda5b581e61396ecc6)
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index e5a7537e47..02328acd98 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -185,6 +185,7 @@ fail:
void
dri_destroy_buffer(__DRIdrawable * dPriv)
{
+ struct dri_context *ctx = dri_context(dPriv->driContextPriv);
struct dri_drawable *drawable = dri_drawable(dPriv);
struct dri_screen *screen = drawable->screen;
struct st_api *stapi = screen->st_api;
@@ -202,6 +203,9 @@ dri_destroy_buffer(__DRIdrawable * dPriv)
/* Notify the st manager that this drawable is no longer valid */
stapi->destroy_drawable(stapi, &drawable->base);
+ if (ctx && ctx->dPriv == dPriv)
+ ctx->dPriv = NULL;
+
FREE(drawable);
}