Merge changes I3f1c1310,Ia8dc3481,I6b19fd63 into nyc-dev
* changes:
malloc_debug: fix multiplication overflow in debug_calloc
malloc_debug: round 0 byte allocations up to 1 byte
malloc_debug: iterate: use usable_size
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index aa6f5f7..568192d 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -282,6 +282,10 @@
return g_dispatch->malloc(size);
}
+ if (size == 0) {
+ size = 1;
+ }
+
size_t real_size = size + g_debug->extra_bytes();
if (real_size < size) {
// Overflow.
@@ -377,6 +381,10 @@
return g_dispatch->memalign(alignment, bytes);
}
+ if (bytes == 0) {
+ bytes = 1;
+ }
+
void* pointer;
if (g_debug->need_header()) {
if (bytes > Header::max_size()) {
@@ -530,8 +538,19 @@
return g_dispatch->calloc(nmemb, bytes);
}
- size_t real_size = nmemb * bytes + g_debug->extra_bytes();
- if (real_size < bytes || real_size < nmemb) {
+ size_t size;
+ if (__builtin_mul_overflow(nmemb, bytes, &size)) {
+ // Overflow
+ errno = ENOMEM;
+ return nullptr;
+ }
+
+ if (size == 0) {
+ size = 1;
+ }
+
+ size_t real_size;
+ if (__builtin_add_overflow(size, g_debug->extra_bytes(), &real_size)) {
// Overflow.
errno = ENOMEM;
return nullptr;
@@ -539,7 +558,7 @@
if (g_debug->need_header()) {
// The above check will guarantee the multiply will not overflow.
- if (bytes * nmemb > Header::max_size()) {
+ if (size > Header::max_size()) {
errno = ENOMEM;
return nullptr;
}
@@ -551,7 +570,7 @@
return nullptr;
}
memset(header, 0, g_dispatch->malloc_usable_size(header));
- return InitHeader(header, header, nmemb * bytes);
+ return InitHeader(header, header, size);
} else {
return g_dispatch->calloc(1, real_size);
}
@@ -594,7 +613,7 @@
if (g_debug->track->Contains(header)) {
// Return just the body of the allocation if we're sure the header exists
ctx->callback(reinterpret_cast<uintptr_t>(g_debug->GetPointer(header)),
- header->real_size(), ctx->arg);
+ header->usable_size, ctx->arg);
return;
}
}
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 28729e8..2503981 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -1290,6 +1290,12 @@
ASSERT_TRUE(pointer == nullptr);
ASSERT_EQ(ENOMEM, errno);
+ const size_t size_t_bits = sizeof(size_t) * 8;
+ const size_t sqrt_size_t = 1ULL << (size_t_bits/2);
+ pointer = debug_calloc(sqrt_size_t + 1, sqrt_size_t);
+ ASSERT_TRUE(pointer == nullptr);
+ ASSERT_EQ(ENOMEM, errno);
+
pointer = debug_realloc(nullptr, SIZE_MAX);
ASSERT_TRUE(pointer == nullptr);
ASSERT_EQ(ENOMEM, errno);