malloc_debug: round 0 byte allocations up to 1 byte
0 byte allocations can cause problems if they are immediately followed
by another allocation with no header, as both allocations will have the
same address. Treat 0 byte allocations as 1 byte allocations so that
debug_iterate will return separate addresses for them.
Bug: 27578580
Change-Id: Ia8dc3481fa7062391e9b3ae58a36e8d47e7ee557
(cherry picked from commit 15af478080cfbfa800fb8172fdf70a84075925e3)
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index fdad541..b20d634 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,7 +538,12 @@
return g_dispatch->calloc(nmemb, bytes);
}
- size_t real_size = nmemb * bytes + g_debug->extra_bytes();
+ size_t size = nmemb * bytes;
+ if (size == 0) {
+ size = 1;
+ }
+
+ size_t real_size = size + g_debug->extra_bytes();
if (real_size < bytes || real_size < nmemb) {
// Overflow.
errno = ENOMEM;
@@ -539,7 +552,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 +564,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);
}