st/nine: Prevent use after free on dtor
authorAxel Davy <davyaxel0@gmail.com>
Sun, 28 Mar 2021 10:26:48 +0000 (12:26 +0200)
committerMarge Bot <eric+marge@anholt.net>
Wed, 14 Apr 2021 08:33:13 +0000 (08:33 +0000)
Found with asan.
This->device was accessed after This was destroyed.

Signed-off-by: Axel Davy <davyaxel0@gmail.com>
Acked-by: Timur Kristóf <timur.kristof@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10160>

src/gallium/frontends/nine/iunknown.c

index 2f3286a..d9b67ab 100644 (file)
@@ -134,12 +134,14 @@ NineUnknown_Release( struct NineUnknown *This )
     ULONG r = p_atomic_dec_return(&This->refs);
 
     if (r == 0) {
+        struct NineDevice9 *device = This->device;
         /* Containers (here with !forward) take care of item destruction */
+
         if (!This->container && This->bind == 0) {
             This->dtor(This);
         }
-        if (This->device) {
-            NineUnknown_Release(NineUnknown(This->device));
+        if (device) {
+            NineUnknown_Release(NineUnknown(device));
         }
     }
     return r;
@@ -156,14 +158,15 @@ NineUnknown_ReleaseWithDtorLock( struct NineUnknown *This )
     ULONG r = p_atomic_dec_return(&This->refs);
 
     if (r == 0) {
+        struct NineDevice9 *device = This->device;
         /* Containers (here with !forward) take care of item destruction */
         if (!This->container && This->bind == 0) {
             NineLockGlobalMutex();
             This->dtor(This);
             NineUnlockGlobalMutex();
         }
-        if (This->device) {
-            NineUnknown_ReleaseWithDtorLock(NineUnknown(This->device));
+        if (device) {
+            NineUnknown_ReleaseWithDtorLock(NineUnknown(device));
         }
     }
     return r;