diff options
author | Dave Airlie <airlied@redhat.com> | 2009-06-10 13:33:47 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-06-24 10:44:11 +1000 |
commit | 07c36e4fdcd93df3d33bdab6cca4780ebc9c1f54 (patch) | |
tree | 10c1d94e9814d95e1b27258c9a263e9df8e3fc1c | |
parent | 184deb9bc325eb7aa7eb7b7d4f98aa917f0269cb (diff) |
dix/resource: fix use after free in resource code with DRI
LookupClientResourceComplex is used by DRI1 code to find and free a DRI
drawable in a callback, however when the DRI code returns this->value
is now pointing at freed memory. It seemed easiest to store the value
to a temporary and return it afterwards.
Another option might be a new FreeClientResourceComplex or one that
also returns the id, so we can free it using an alternative means.
found using valgrind.
amended along ajax's suggestions
-rw-r--r-- | dix/resource.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/dix/resource.c b/dix/resource.c index 73bc3a998..d3641df8d 100644 --- a/dix/resource.c +++ b/dix/resource.c @@ -707,7 +707,8 @@ LookupClientResourceComplex( pointer cdata ){ ResourcePtr *resources; - ResourcePtr this; + ResourcePtr this, next; + pointer value; int i; if (!client) @@ -715,10 +716,13 @@ LookupClientResourceComplex( resources = clientTable[client->index].resources; for (i = 0; i < clientTable[client->index].buckets; i++) { - for (this = resources[i]; this; this = this->next) { + for (this = resources[i]; this; this = next) { + next = this->next; if (!type || this->type == type) { - if((*func)(this->value, this->id, cdata)) - return this->value; + /* workaround func freeing the type as DRI1 does */ + value = this->value; + if((*func)(value, this->id, cdata)) + return value; } } } |