[PATCH] glx: Refcnt the GLXDrawable to avoid use after free with multiple FreeResource
Michel Dänzer
michel at daenzer.net
Thu Dec 16 09:29:13 PST 2010
On Don, 2010-12-16 at 11:54 -0500, Kristian Høgsberg wrote:
> From: Chris Wilson <chris at chris-wilson.co.uk>
>
> Although there may be more than one resource handles pointing to the
> Drawable, we only want to destroy it once and only reference the
> resource which may have just been deleted on the first instance.
>
> v2: Apply fixes and combine with another bug fix from Michel Dänzer,
> https://bugs.freedesktop.org/show_bug.cgi?id=28181
> v3: Just use the refcnt and don't try to free other resources in the
> DrawableGone callback.
>
> Signed-off-by: Kristian Høgsberg <krh at bitplanet.net>
>
> Can we just do this instead? Didn't test the patch, but this should do
> the same and actually simplifies the code.
>
> Kristian
>
> ---
> glx/glxcmds.c | 13 +++++++++----
> glx/glxdrawable.h | 2 ++
> glx/glxext.c | 13 +++----------
> 3 files changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/glx/glxcmds.c b/glx/glxcmds.c
> index 8d13c15..1e8044b 100644
> --- a/glx/glxcmds.c
> +++ b/glx/glxcmds.c
> @@ -1131,14 +1133,17 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen,
>
> /* Add the glx drawable under the XID of the underlying X drawable
> * too. That way we'll get a callback in DrawableGone and can
> * clean up properly when the drawable is destroyed. */
> - if (drawableId != glxDrawableId &&
> - !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
> - pGlxDraw->destroy (pGlxDraw);
> - return BadAlloc;
> + if (drawableId != glxDrawableId) {
> + if (!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
> + pGlxDraw->destroy (pGlxDraw);
> + return BadAlloc;
> + }
> + pGlxDraw->refcnt++;
The fixed version of this part from Chris' v2 patch is needed.
> diff --git a/glx/glxext.c b/glx/glxext.c
> index f5ebe4f..499567a 100644
> --- a/glx/glxext.c
> +++ b/glx/glxext.c
> @@ -126,16 +126,9 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
> {
> __GLXcontext *c, *next;
>
> - /* If this drawable was created using glx 1.3 drawable
> - * constructors, we added it as a glx drawable resource under both
> - * its glx drawable ID and it X drawable ID. Remove the other
> - * resource now so we don't a callback for freed memory. */
> - if (glxPriv->drawId != glxPriv->pDraw->id) {
> - if (xid == glxPriv->drawId)
> - FreeResourceByType(glxPriv->pDraw->id, __glXDrawableRes, TRUE);
> - else
> - FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE);
> - }
> + glxPriv->refcnt--;
> + if (glxPriv->refcnt > 0)
> + return True;
If the IDs are different, doesn't this mean the GLX drawable will never
actually be destroyed before the X drawable?
--
Earthling Michel Dänzer | http://www.vmware.com
Libre software enthusiast | Debian, X and DRI developer
More information about the xorg-devel
mailing list