From a9fa017d82b1434a0597682b1232e61d92c80645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 1 Jun 2006 18:14:59 +0000 Subject: [PATCH] map_backing_store() did not acquire a cache ref in case it created a private mapping, but it connected the vm_cache objects, so if it failed later, and thus called vm_cache_release_ref() the object could have been freed accidently. Most uses of map_backing_store() explicetly acquired a cache_ref *after* the call was successful, but _vm_map_file() did not do this. _vm_map_file() might still not work correctly, though, need to have a closer look at it. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17692 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/vm/vm.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 1df0496ae1..9fbe433fe5 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -553,6 +553,7 @@ map_backing_store(vm_address_space *addressSpace, vm_store *store, void **_virtu newCache->scan_skip = cache->scan_skip; newCache->source = cache; + vm_cache_acquire_ref(cacheRef); cache = newCache; cacheRef = cache->ref; @@ -1271,8 +1272,13 @@ vm_clone_area(team_id team, const char *name, void **address, uint32 addressSpec address, sourceArea->cache_offset, sourceArea->size, addressSpec, sourceArea->wiring, protection, mapping, &newArea, name); } - if (status == B_OK) + if (status == B_OK && mapping != REGION_PRIVATE_MAP) { + // If the mapping is REGION_PRIVATE_MAP, map_backing_store() needed + // to create a new ref, and has therefore already acquired a reference + // to the source cache - but otherwise it has no idea that we need + // one. vm_cache_acquire_ref(sourceArea->cache_ref); + } vm_put_area(sourceArea); vm_put_address_space(addressSpace); @@ -1540,7 +1546,11 @@ vm_copy_area(team_id addressSpaceID, const char *name, void **_address, uint32 a if (status < B_OK) goto err; - vm_cache_acquire_ref(cacheRef); + if (!writableCopy) { + // map_backing_store() cannot know it has to acquire a ref to + // the store for REGION_NO_PRIVATE_MAP + vm_cache_acquire_ref(cacheRef); + } // If the source area is writable, we need to move it one layer up as well