Fix potential invalid memory access in surface force field BVH tree.
authorAndrew Williams <sobakasu>
Tue, 22 Jan 2019 11:51:14 +0000 (12:51 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Tue, 22 Jan 2019 14:24:06 +0000 (15:24 +0100)
Free the BVH tree immediately along with the mesh, otherwise we might access
invalid mesh data.

Differential Revision: https://developer.blender.org/D4201

source/blender/blenkernel/intern/bvhutils.c
source/blender/blenlib/intern/BLI_kdopbvh.c
source/blender/modifiers/intern/MOD_surface.c

index c264eb8a1d219a7ce90908950a016b2dd68ef2af..644672c52fcc79a7ea9d1fb53a17391d579a9a7f 100644 (file)
@@ -1112,6 +1112,8 @@ BVHTree *BKE_bvhtree_from_mesh_get(
                        data_cp.vert = mesh->mvert;
 
                        if (data_cp.cached == false) {
+                               /* TODO: a global mutex lock held during the expensive operation of
+                                * building the BVH tree is really bad for performance. */
                                BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
                                data_cp.cached = bvhcache_find(
                                        mesh->runtime.bvh_cache, type, &data_cp.tree);
index d497c7a83ab71c8751f5b71e89f4797072ad2c09..2819c1c5943f9500d8109c651087f94d5866ecfd 100644 (file)
@@ -908,23 +908,17 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
 
 
 fail:
-       MEM_SAFE_FREE(tree->nodes);
-       MEM_SAFE_FREE(tree->nodebv);
-       MEM_SAFE_FREE(tree->nodechild);
-       MEM_SAFE_FREE(tree->nodearray);
-
-       MEM_freeN(tree);
-
+       BLI_bvhtree_free(tree);
        return NULL;
 }
 
 void BLI_bvhtree_free(BVHTree *tree)
 {
        if (tree) {
-               MEM_freeN(tree->nodes);
-               MEM_freeN(tree->nodearray);
-               MEM_freeN(tree->nodebv);
-               MEM_freeN(tree->nodechild);
+               MEM_SAFE_FREE(tree->nodes);
+               MEM_SAFE_FREE(tree->nodearray);
+               MEM_SAFE_FREE(tree->nodebv);
+               MEM_SAFE_FREE(tree->nodechild);
                MEM_freeN(tree);
        }
 }
index c5fa510f2e0f525a21449ea5f656fcaa0974cfbe..a7198b5721ee3a924f81998bb603aab0c3d6cabd 100644 (file)
@@ -96,8 +96,15 @@ static void deformVerts(
        SurfaceModifierData *surmd = (SurfaceModifierData *) md;
        const int cfra = (int)DEG_get_ctime(ctx->depsgraph);
 
+       /* Free mesh and BVH cache. */
+       if (surmd->bvhtree) {
+               free_bvhtree_from_mesh(surmd->bvhtree);
+               MEM_SAFE_FREE(surmd->bvhtree);
+       }
+
        if (surmd->mesh) {
                BKE_id_free(NULL, surmd->mesh);
+               surmd->mesh = NULL;
        }
 
        if (mesh) {
@@ -168,10 +175,7 @@ static void deformVerts(
 
                surmd->cfra = cfra;
 
-               if (surmd->bvhtree)
-                       free_bvhtree_from_mesh(surmd->bvhtree);
-               else
-                       surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
+               surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
 
                if (surmd->mesh->totpoly)
                        BKE_bvhtree_from_mesh_get(surmd->bvhtree, surmd->mesh, BVHTREE_FROM_LOOPTRI, 2);