1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 10:48:11 +00:00

Kernel: Declare operator new/delete as noexcept for the Kernel

For Kernel OOM hardening to work correctly, we need to be able to
call a "nothrow" version of operator new. Unfortunately the default
"throwing" version of operator new assumes that the allocation will
never return on failure and will always throw an exception. This isn't
true in the Kernel, as we don't have exceptions. So if we call the
normal/throwing new and kmalloc returns NULL, the generated code will
happily go and dereference that NULL pointer by invoking the constructor
before we have a chance to handle the failure.

To fix this we declare operator new as noexcept in the Kernel headers,
which will allow the caller to actually handle allocation failure.

The delete implementations need to match the prototype of the new which
allocated them, so we need define delete as noexcept as well. GCC then
errors out declaring that you should implement sized delete as well, so
this change provides those stubs in order to compile cleanly.

Finally the new operator definitions have been standardized as being
declared with [[nodiscard]] to avoid potential memory leaks. So lets
declares the kernel versions that way as well.
This commit is contained in:
Brian Gianforcaro 2021-05-11 01:17:04 -07:00 committed by Andreas Kling
parent 8b079a6b0d
commit 97adaaf933
2 changed files with 29 additions and 2 deletions

View file

@ -264,16 +264,36 @@ void* krealloc(void* ptr, size_t new_size)
return g_kmalloc_global->m_heap.reallocate(ptr, new_size);
}
void* operator new(size_t size)
void* operator new(size_t size) noexcept
{
return kmalloc(size);
}
void* operator new[](size_t size)
void* operator new[](size_t size) noexcept
{
return kmalloc(size);
}
void operator delete(void* ptr) noexcept
{
return kfree(ptr);
}
void operator delete(void* ptr, size_t) noexcept
{
return kfree(ptr);
}
void operator delete[](void* ptr) noexcept
{
return kfree(ptr);
}
void operator delete[](void* ptr, size_t) noexcept
{
return kfree(ptr);
}
void get_kmalloc_stats(kmalloc_stats& stats)
{
ScopedSpinLock lock(s_lock);