Rederive allocator id for remotes.

Storing a pointer to an allocator id in an unused object could be a
gadget for escallating priviledge of an attacker, by enabling
use-after-free to corrupt the allocator structure, and then create more
damage.

This commit adds an alternative implementation that does not cache the
allocator id.
This commit is contained in:
Matthew Parkinson
2021-04-09 08:35:00 +01:00
committed by Matthew Parkinson
parent b3796c123e
commit 208ab9a8e8
2 changed files with 50 additions and 11 deletions

View File

@@ -734,16 +734,11 @@ namespace snmalloc
SNMALLOC_FAST_PATH void handle_dealloc_remote(CapPtr<Remote, CBAlloc> p)
{
if (likely(p->trunc_target_id() == get_trunc_id()))
if (likely(Remote::trunc_target_id(p, &large_allocator) == get_trunc_id()))
{
// Destined for my slabs
auto p_auth = large_allocator.template capptr_amplify<Remote>(p);
auto super = Superslab::get(p_auth);
check_client(
p->trunc_target_id() == super->get_allocator()->trunc_id(),
"Detected memory corruption. Potential use-after-free");
dealloc_not_large_local(super, p, p->sizeclass());
}
else
@@ -751,7 +746,7 @@ namespace snmalloc
// Merely routing; despite the cast here, p is going to be cast right
// back to a Remote.
remote.dealloc<Allocator>(
p->trunc_target_id(),
Remote::trunc_target_id(p, &large_allocator),
p.template as_reinterpret<FreeObject>(),
p->sizeclass());
}