Convert alloc paths to capptr::Alloc<void>

The use of void* had let an overzealous unsafe_ptr() leak a pointer with address
space control to the client (in LocalAllocator::alloc_not_small, specifically).
Correct this to call capptr_chunk_is_alloc() (to capture our intent) and
capptr_to_user_address_control() (to do the bounding) and defer the conversion
to void* until the very periphery of the allocator, using capptr_reveal()
(again, to capture intent).
This commit is contained in:
Nathaniel Wesley Filardo
2021-10-20 02:49:32 +01:00
committed by Nathaniel Wesley Filardo
parent 31b8d99ca6
commit 5bb556cb68
3 changed files with 19 additions and 20 deletions

View File

@@ -167,7 +167,7 @@ namespace snmalloc
* passed to the core allocator.
*/
template<ZeroMem zero_mem>
SNMALLOC_SLOW_PATH void* alloc_not_small(size_t size)
SNMALLOC_SLOW_PATH capptr::Alloc<void> alloc_not_small(size_t size)
{
if (size == 0)
{
@@ -203,12 +203,12 @@ namespace snmalloc
chunk.unsafe_ptr(), size);
}
return chunk.unsafe_ptr();
return capptr_chunk_is_alloc(capptr_to_user_address_control(chunk));
});
}
template<ZeroMem zero_mem>
SNMALLOC_FAST_PATH void* small_alloc(size_t size)
SNMALLOC_FAST_PATH capptr::Alloc<void> small_alloc(size_t size)
{
// SNMALLOC_ASSUME(size <= sizeclass_to_size(NUM_SIZECLASSES));
auto domesticate = [this](freelist::QueuePtr p)
@@ -430,11 +430,10 @@ namespace snmalloc
{
// Small allocations are more likely. Improve
// branch prediction by placing this case first.
return small_alloc<zero_mem>(size);
return capptr_reveal(small_alloc<zero_mem>(size));
}
// TODO capptr_reveal?
return alloc_not_small<zero_mem>(size);
return capptr_reveal(alloc_not_small<zero_mem>(size));
#endif
}