[PATCH v2] glx: Fix use after free in DrawableGone
Kristian Høgsberg
krh at bitplanet.net
Mon Sep 27 05:42:39 PDT 2010
2010/9/23 Kristian Høgsberg <krh at bitplanet.net>:
> 2010/9/23 Jeremy Huddleston <jeremyhu at apple.com>:
>> That seems off to me. This is doing more than changing the c->next dereference. You're now freeing it where you weren't before.
>>
>> Previously, you freed it inside:
>> if (c->isCurrent && (c->drawPriv == glxPriv || c->readPriv == glxPriv))
>> if(!c->idExists)
>>
>> Now, you free it inside:
>> if (!c->idExists && !c->isCurrent)
>>
>> So you're missing the check for (c->drawPriv == glxPriv || c->readPriv == glxPriv) ... is that intentional and we had a leak before, or are we now over-releasing?
>
> All the contexts on the context list have either idExists or isCurrent
> or both true, otherwise we would have already destroyed them. If a
> context that was current is destroyed, we set idExists to NULL (it no
> longer has an XID) but keep it around while it's still current. If
> the context is not current, we just destroy it right away and take it
> out of the list.
>
> The loop above, iterates through the list of all contexts to see if
> there is a context that has been destroyed but is still current with
> the drawable that we're getting the DrawableGone() callback for. We
> treat that as an unbind, which triggers the context destruction. As
> Jon mentions, that may not be the right thing to do, but in the scope
> of this patch, we're just delaying the destroy until we're done
> touching the context.
Jeremy, does the above explanation satisfy your concerns? Keith, do
you want to pick this up for master?
>> On Sep 23, 2010, at 06:04, Kristian Høgsberg wrote:
>>
>>> Signed-off-by: Kristian Høgsberg <krh at bitplanet.net>
>>> ---
>>>
>>> Chris Wilson points out that we were still accessing c->next after free.
>>> Here's an updated version that fixes that.
>>>
>>> Kristian
>>>
>>> glx/glxext.c | 11 +++++------
>>> 1 files changed, 5 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/glx/glxext.c b/glx/glxext.c
>>> index e203156..f5ebe4f 100644
>>> --- a/glx/glxext.c
>>> +++ b/glx/glxext.c
>>> @@ -124,7 +124,7 @@ static int glxBlockClients;
>>> */
>>> static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
>>> {
>>> - __GLXcontext *c;
>>> + __GLXcontext *c, *next;
>>>
>>> /* If this drawable was created using glx 1.3 drawable
>>> * constructors, we added it as a glx drawable resource under both
>>> @@ -137,7 +137,8 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
>>> FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE);
>>> }
>>>
>>> - for (c = glxAllContexts; c; c = c->next) {
>>> + for (c = glxAllContexts; c; c = next) {
>>> + next = c->next;
>>> if (c->isCurrent && (c->drawPriv == glxPriv || c->readPriv == glxPriv)) {
>>> int i;
>>>
>>> @@ -160,15 +161,13 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
>>> }
>>> }
>>> }
>>> -
>>> - if (!c->idExists) {
>>> - __glXFreeContext(c);
>>> - }
>>> }
>>> if (c->drawPriv == glxPriv)
>>> c->drawPriv = NULL;
>>> if (c->readPriv == glxPriv)
>>> c->readPriv = NULL;
>>> + if (!c->idExists && !c->isCurrent)
>>> + __glXFreeContext(c);
>>> }
>>>
>>> glxPriv->destroy(glxPriv);
>>> --
>>> 1.7.3
>>>
>>> _______________________________________________
>>> xorg-devel at lists.x.org: X.Org development
>>> Archives: http://lists.x.org/archives/xorg-devel
>>> Info: http://lists.x.org/mailman/listinfo/xorg-devel
>>
>>
>
More information about the xorg-devel
mailing list