Add checks for deallocation with size (#160)
Ensure that the size deallocated with is the correct size. If the size supplied is wrong, then internal invariants can break.
This commit is contained in:
committed by
GitHub
parent
06eef5c4c5
commit
7bb00a7169
@@ -199,6 +199,35 @@ namespace snmalloc
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the allocation at `p` could have been validly allocated with
|
||||
* a size of `size`.
|
||||
*/
|
||||
void check_size(void* p, size_t size)
|
||||
{
|
||||
#if defined(CHECK_CLIENT)
|
||||
auto asize = alloc_size(p);
|
||||
auto asc = size_to_sizeclass(asize);
|
||||
if (size_to_sizeclass(size) != asc)
|
||||
{
|
||||
// Correction for large classes.
|
||||
if (asc > NUM_SIZECLASSES)
|
||||
{
|
||||
if (bits::next_pow2(size) != asize)
|
||||
error("Deallocating with incorrect size supplied.");
|
||||
}
|
||||
// Correction for zero sized allocations.
|
||||
else if ((size != 0) && (asc != 0))
|
||||
{
|
||||
error("Deallocating with incorrect size supplied.");
|
||||
}
|
||||
}
|
||||
#else
|
||||
UNUSED(p);
|
||||
UNUSED(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Free memory of a statically known size. Must be called with an
|
||||
* external pointer.
|
||||
@@ -210,6 +239,7 @@ namespace snmalloc
|
||||
UNUSED(size);
|
||||
return free(p);
|
||||
#else
|
||||
check_size(p, size);
|
||||
constexpr sizeclass_t sizeclass = size_to_sizeclass_const(size);
|
||||
|
||||
if (sizeclass < NUM_SMALL_CLASSES)
|
||||
@@ -249,6 +279,7 @@ namespace snmalloc
|
||||
UNUSED(size);
|
||||
return free(p);
|
||||
#else
|
||||
check_size(p, size);
|
||||
if (likely((size - 1) <= (sizeclass_to_size(NUM_SMALL_CLASSES - 1) - 1)))
|
||||
{
|
||||
Superslab* super = Superslab::get(p);
|
||||
|
||||
Reference in New Issue
Block a user