From 075c2eca0624e031b548c41272f44ce9b9d38889 Mon Sep 17 00:00:00 2001 From: Bart van der Braak Date: Tue, 19 Aug 2025 12:26:13 +0200 Subject: [PATCH] Fix #144483: Use-after-free when splitting View3D opened Asset Shelf `asset_shelf::regiondata_duplicate()` first creates a shallow copy of the `AssetShelf`, including its `AssetShelfSettings` member. So the contained pointer point to the same memory. While this is a rather unusual case for a copy assignment operator to consider, I think this is fine since the API allows these shadow copies. This is a bit of a consequence of mixing C and C++ style memory management. Pull Request: https://projects.blender.org/blender/blender/pulls/144613 --- source/blender/blenlib/BLI_listbase.h | 4 ++++ .../editors/asset/intern/asset_shelf_settings.cc | 11 ++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 1a80582d7f2..d2352da429a 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -395,6 +395,10 @@ BLI_INLINE bool operator==(const ListBase &a, const ListBase &b) { return BLI_listbase_equal(&a, &b); } +BLI_INLINE bool operator!=(const ListBase &a, const ListBase &b) +{ + return !(a == b); +} template T *BLI_listbase_find(const ListBase &listbase, Fn &&predicate) { diff --git a/source/blender/editors/asset/intern/asset_shelf_settings.cc b/source/blender/editors/asset/intern/asset_shelf_settings.cc index e4c84edea1c..cc31ae97166 100644 --- a/source/blender/editors/asset/intern/asset_shelf_settings.cc +++ b/source/blender/editors/asset/intern/asset_shelf_settings.cc @@ -41,9 +41,14 @@ AssetShelfSettings &AssetShelfSettings::operator=(const AssetShelfSettings &othe return *this; /* Handle self-assignment safely. */ } - /* Free existing properties. */ - BKE_asset_catalog_path_list_free(this->enabled_catalog_paths); - MEM_SAFE_FREE(this->active_catalog_path); + /* Free existing properties. Check if they point to the same memory first, #AssetShelfSettings + * might have been shallow copied before. */ + if (this->enabled_catalog_paths != other.enabled_catalog_paths) { + BKE_asset_catalog_path_list_free(this->enabled_catalog_paths); + } + if (this->active_catalog_path != other.active_catalog_path) { + MEM_SAFE_FREE(this->active_catalog_path); + } /* Copy from 'other'. */ this->asset_library_reference = other.asset_library_reference;